http://codeforces.com/problemset/problem/1252/G
题意:
给出n个人,每个人有个唯一的能力值,你是第一个人。现在有m次轮换,将每次将 个能力值较小的换出,塞入 个新的人。
有q次询问,每次更改m次中的某一次的某个人的能力值,问你是否可以生存到最后。
解析:
显然对于人数为 的这次轮换,大于你的人的个数最大为 。设定初始值
对于第i次轮换假设换入x个大于你的,那么相当于 都加上x。
如果某次更改后有一个位置大于0,说明不行。
代码:
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
const int maxn=1e5+9;
int n,m,q;
int base;
int a[maxn];
vector<int>V[maxn];
#define ls (rt<<1)
#define rs (rt<<1|1)
#define mid (l+r>>1)
int mx[maxn<<2];
int laz[maxn<<2];
void build(int rt,int l,int r){
laz[rt]=0;
if(l==r){
mx[rt]=a[l];
return ;
}
build(ls,l,mid);
build(rs,mid+1,r);
mx[rt]=max(mx[ls],mx[rs]);
}
void down(int rt){
if(laz[rt]){
int &x=laz[rt];
laz[ls]+=x;
laz[rs]+=x;
mx[ls]+=x;
mx[rs]+=x;
x=0;
}
}
void update(int rt,int l,int r,int L,int R,int v){
if(l>=L&&r<=R){
mx[rt]+=v;
laz[rt]+=v;
return;
}
down(rt);
if(L<=mid)update(ls,l,mid,L,R,v);
if(R>mid)update(rs,mid+1,r,L,R,v);
mx[rt]=max(mx[ls],mx[rs]);
}
int query(int rt,int l,int r,int L,int R){
if(l>=L&&r<=R){
return mx[rt];
}
down(rt);
int res=-2e9;
if(L<=mid)res=query(ls,l,mid,L,R);
if(R>mid)res=max(res,query(rs,mid+1,r,L,R));
return res;
}
void debug(int m){
printf("debug :");
rep(i,1,m){
printf("%d ",query(1,1,m,i,i));
}
puts("");
}
int main(){
scanf("%d%d%d",&n,&m,&q);
scanf("%d",&base);
rep(i,1,n-1){
int tmp;scanf("%d",&tmp);
if(tmp>base)a[1]++;
}
int K;
rep(i,1,m){
scanf("%d",&K);
rep(j,1,K){
int tmp;scanf("%d",&tmp);
V[i].push_back(tmp);
if(tmp>base){
a[i+1]++;
}
}
}
rep(i,2,m)a[i]+=a[i-1];
rep(i,1,m)a[i]-=n-V[i].size()-1;
build(1,1,m);
// debug(m);
while(q--){
int I,J,v;scanf("%d%d%d",&I,&J,&v);
J--;
bool s1=0,s2=0;
if(V[I][J]>base)s1=1;
if(v>base)s2=1;
V[I][J]=v;
if(s1!=s2&&I!=m){
if(s1){
update(1,1,m,I+1,m,-1);
}
else{
update(1,1,m,I+1,m,1);
}
}
int Max=query(1,1,m,1,m);
if(Max>0)puts("0");
else puts("1");
// debug(m);
}
}