题目链接:https://ac.nowcoder.com/acm/contest/923/E
题目大意:


思路:矩阵中每个元素都是a[i]+b[j],那么如果a[i]和b[j]都越小,那么这个矩阵元素值就越小。

用multiset维护一下,a[i]和b[i]。每次查询时,优先队列暴力得到前k个就行了。
重点讲一下:优先队列暴力
优先队列的状态为:

struct node
{
    multiset<int>::iterator a,b;
    bool operator<(const node &c)const
    {
        return ((*a)+(*b))>((*c.a)+(*c.b));
    }
} x,tp;


如果当前最小值为{1, 1}那么比{1, 1}稍微大的数只能是{1, 2}或者{2, 1}。当时不能由一个状态转移到两个状态。会出现状态重复。因为如果这样的话,{1, 2},{2, 1}都能够转化到{2, 2}那么{2, 2}就重复出现在队列中。

我们要对转化加限制。

我们现在证明一下正确性:

可以自己画图理解一下:
对于一个出现的状态{x, y}, 队列中如果有{x, z}, {z<y}的状态存在,那么对于{x, y} y!=1扩展出{x, y+1}肯定不是最优解。

如果没有那么说明{x, y+1} 已经扩展出来了。更不用去扩展了。
#include<bits/stdc++.h>
using namespace std;
#define N 101010
#define ll long long
#define go(i,a,b) for(int i=a;i<=b;i++)
int n,m,zzz,a[N],b[N],op,nowx,nowy;
struct node
{
    multiset<int>::iterator a,b;
    bool operator<(const node &c)const
    {
        return ((*a)+(*b))>((*c.a)+(*c.b));
    }
} x,tp;
multiset<int>r,c;
priority_queue<node>q;
char s[15];
int main()
{
    scanf("%d%d%d",&n,&m,&zzz);
    go(i,0,n-1)scanf("%d",&a[i]);
    go(i,0,m-1)scanf("%d",&b[i]);
    c.insert(b[0]),r.insert(a[0]);
    go(qq,1,zzz)
    {
        scanf("%s%d",s,&op);
        if(s[0]=='Q')
        {
            x.a=r.begin();
            x.b=c.begin();
            q.push(x);
            while(op--)
            {
                tp=q.top();
                q.pop();
                printf("%d%c",*(tp.a)+*(tp.b),op==0?'\n':' ');
                x=tp;

                tp.a++;
                if(tp.a!=r.end())
                    q.push(tp);

                if(x.a==r.begin())//保证b[i](i=1)
                {
                    x.b++;
                    if(x.b!=c.end())
                    q.push(x);

                }
            }
            while(!q.empty())
                q.pop();
        }
        else if(s[0]=='R')
        {
            int i=nowy+1;
            nowy=min(nowy+op,m-1);
            for(i; i<=nowy; i++)
                c.insert(b[i]);
        }
        else if(s[0]=='D')
        {
            int i=nowx+1;
            nowx=min(nowx+op,n-1);
            for(i; i<=nowx; i++)
                r.insert(a[i]);
        }
    }
    return 0;
}