原题链接:https://codeforces.ml/contest/1252/problem/G
题意
一个公司有n个人,每年有若干个人应聘,每次都会开除排名倒数的若干个人并将所有应聘的人招进公司,接下来有q次修改,每次可以修改每年应聘人的能力值,并询问1号员工能否在m年后仍然在公司
分析
如果直接暴力去模拟肯定是不行的,因为O(qm)的复杂度就已经超时了,这时要想办法去优化查询。
首先肯定要预处理出没有修改时当前员工在每年的排名情况,并且当前排名还要加上下一年招的人数,如果这个值大于n,那么这个人就会被踢出公司。
然后我们考虑修改的情况,如果将应聘的能力值低的人换成能力值高的人,那么1号员工在那一年起的排名都会增加1,反之会减少1,这里的区间加和区间减可以用线段树去维护,并且在查询时求一个区间最大值,如果大于n就不在公司里了。
Code
#include <bits/stdc++.h>
using namespace std;
//#define ACM_LOCAL
#define re register
#define fi first
#define se second
const int N = 2e5 + 10;
const int M = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int MOD = 1e9 + 7;
typedef long long ll;
typedef pair<int, int> PII;
int a[N], num[N], now[N];
vector<int> ve[N], cp[N];
struct node {
int l, r;
int maxx, tag;
}t[N<<2];
void push_up(int u) {
t[u].maxx = max(t[u<<1].maxx, t[u<<1|1].maxx);
}
void push_down(int u) {
if (t[u].tag) {
t[u<<1].tag += t[u].tag;
t[u<<1|1].tag += t[u].tag;
t[u<<1].maxx += t[u].tag;
t[u<<1|1].maxx += t[u].tag;
t[u].tag = 0;
}
}
void build(int u, int l, int r) {
t[u].l = l, t[u].r = r, t[u].tag = 0;
if (l == r) {
t[u].maxx = now[l];
return;
}
int mid = (l + r) >> 1;
build(u<<1, l, mid);
build(u<<1|1, mid+1, r);
push_up(u);
}
void modify(int u, int ql, int qr, int val) {
if (ql <= t[u].l && qr >= t[u].r) {
t[u].maxx += val;
t[u].tag += val;
return;
}
push_down(u);
int mid = (t[u].l + t[u].r) >> 1;
if (ql <= mid) modify(u<<1, ql, qr, val);
if (qr > mid) modify(u<<1|1, ql, qr, val);
push_up(u);
}
int query(int u, int ql, int qr) {
if (ql <= t[u].l && qr >= t[u].r) return t[u].maxx;
push_down(u);
int mid = (t[u].l + t[u].r) >> 1;
int Max = 0;
if (ql <= mid) Max = max(Max, query(u<<1, ql, qr));
if (qr > mid) Max = max(Max, query(u<<1|1, ql, qr));
return Max;
}
void solve() {
int n, m, q; cin >> n >> m >> q;
for (int i = 1; i <= n; i++) cin >> a[i];
int val = a[1]; sort(a+1, a+n+1);
now[1] = n - (lower_bound(a+1, a+n+1, val) - a - 1);
for (int i = 1; i <= m; i++) {
cin >> num[i];
for (int j = 1; j <= num[i]; j++) {
int x; cin >> x;
ve[i].push_back(x);
cp[i].push_back(x);
}
sort(cp[i].begin(), cp[i].end());
now[i+1] = now[i] + num[i] - (lower_bound(cp[i].begin(), cp[i].end(), val) - cp[i].begin());
}
for (int i = 1; i <= m; i++) now[i] += num[i];
build(1, 1, m);
for (int i = 1; i <= q; i++) {
int x, y, z; cin >> x >> y >> z;
int dig = ve[x][y-1];
int add = -(dig > val) + (z > val);
if (x != m) modify(1, x+1, m, add);
printf("%d\n", query(1, 1, m) > n ? 0 : 1);
ve[x][y-1] = z;
}
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#ifdef ACM_LOCAL
freopen("input", "r", stdin);
freopen("output", "w", stdout);
#endif
solve();
}