思路:
优先队列,将迭代器变量作为结构体的变量。
迭代器走的时候只能像一个方向走,另外一个方向只有最开始才走。如下图所示:
如果两个方向同时走,同一个值会被遍历多次,像上图那样就能保证每个位置都走到且只走一次。
代码:
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define y1 y11 #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pli pair<LL, int> #define pii pair<int, int> #define piii pair<pii, int> #define pdd pair<double, double> #define mem(a, b) memset(a, b, sizeof(a)) #define debug(x) cerr << #x << " = " << x << " "; #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); //head const int N = 1e5 + 5; int n, m, q, k; int a[N], b[N]; char op[10]; multiset<int> sa, sb; struct Node { int x; multiset<int>::iterator pa, pb; bool operator < (const Node & rhs) const { return x > rhs.x; } }; int main() { scanf("%d %d %d", &n, &m, &q); for (int i = 1; i <= n; ++i) scanf("%d", &a[i]); for (int i = 1; i <= m; ++i) scanf("%d", &b[i]); int x = 1, y = 1; sa.insert(a[1]), sb.insert(b[1]); while(q--) { scanf("%s %d", op, &k); if(op[0] == 'R') { int ny = min(m, y+k); for (int i = y+1; i <= ny; ++i) sb.insert(b[i]); y = ny; } else if(op[0] == 'D') { int nx = min(n, x+k); for (int i = x+1; i <= nx; ++i) sa.insert(a[i]); x = nx; } else { priority_queue<Node> q; q.push({*sa.begin()+*sb.begin(), sa.begin(), sb.begin()}); for (int i = 1; i <= k; ++i) { Node t = q.top(); q.pop(); printf("%d%c", t.x, " "[i==k]); if(t.pa == sa.begin()) { auto tp = t.pb; ++tp; if(tp != sb.end()) q.push({*t.pa+*tp, t.pa, tp}); } auto ta = t.pa; ++ta; if(ta != sa.end()) q.push({*ta+*t.pb, ta, t.pb}); } } } return 0; }