CodeForces - 1179C Serge and Dining Room
阿新 • • 發佈:2020-08-22
\(\text{Description}\)
\(\text{Solution}\)
你會發現這道題和先後順序沒有關係,對於一道菜,只要能買這個菜的人發現它能買的菜沒有或買光了,這個菜就會被買。
我們線上段樹上以菜為 \(1\),人為 \(-1\),每來一個菜或人就就將其權值插入 \([1,val]\)。這樣找到最大權值大於 \(0\) 的即為答案。
\(\text{Code}\)
#include<cstdio> #include<iostream> using namespace std; const int N = 300002, Limit = 1000000; int n, m, q, a[N], b[N], st[Limit << 2], la[Limit << 2]; void pushDown(const int u) { if(la[u]) { la[u << 1] += la[u]; la[u << 1 | 1] += la[u]; st[u << 1] += la[u]; st[u << 1 | 1] += la[u]; la[u] = 0; } } void add(const int id, const int l, const int r, const int L, const int R, const int num) { if(L <= l && R >= r) { la[id] += num; st[id] += num; return; } pushDown(id); int mid = l + r >> 1; if(L <= mid) add(id << 1, l, mid, L, R, num); if(R > mid) add(id << 1 | 1, mid + 1, r, L, R, num); st[id] = max(st[id << 1], st[id << 1 | 1]); } int ask(const int id, const int l, const int r) { if(l == r) return l; int mid = l + r >> 1; pushDown(id);//C if(st[id << 1 | 1] > 0)//D return ask(id << 1 | 1, mid + 1, r); return ask(id << 1, l, mid); } int main() { int f, x, y; scanf("%d %d", &n, &m); for(int i = 1; i <= n; i ++) { scanf("%d", &a[i]); add(1, 1, Limit, 1, a[i], 1);//E } for(int i = 1; i <= m; i ++) { scanf("%d", &b[i]); add(1, 1, Limit, 1, b[i], -1); } scanf("%d", &q); while(q --) { scanf("%d %d %d", &f, &x, &y); if(f == 1) { add(1, 1, Limit, 1, a[x], -1);//A add(1, 1, Limit, 1, y, 1); a[x] = y; } else { add(1, 1, Limit, 1, b[x], 1); add(1, 1, Limit, 1, y, -1); b[x] = y; } if(st[1] > 0)//B printf("%d\n", ask(1, 1, Limit)); else printf("-1\n"); } return 0; }