CF风格题,先猜结论,记数列中i这个数共出现了cnt[i]次,那么所有区间[i-cnt[i]+1,i]的并集的补集大小就是答案。
于是我们只需要线段树维护每个位置是否被某个区间覆盖到即可,对于整体加减操作,设一个偏移量即可。
1 #include<cstdio> 2 #include<algorithm> 3 #define ls (x<<1) 4 #define rs (ls|1) 5 #define lson ls,L,mid 6 #define rson rs,mid+1,R 7 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 8 using namespace std; 9 10 const int N=600010; 11 int n,m,mx,py,L,p,x,a[N],num[N],v[N<<2],c[N<<2],mn[N<<2],tag[N<<2]; 12 13 void upd(int x){ 14 if (mn[ls]<mn[rs]) mn[x]=mn[ls],c[x]=c[ls]; 15 else if (mn[ls]>mn[rs]) mn[x]=mn[rs],c[x]=c[rs]; 16 else mn[x]=mn[ls],c[x]=c[ls]+c[rs]; 17 if (!mn[x]) v[x]=c[x]; else v[x]=0; 18 } 19 20 void put(int x,int k){ 21 mn[x]+=k; tag[x]+=k; 22 if (!mn[x]) v[x]=c[x]; else v[x]=0; 23 } 24 25 void push(int x){ 26 if (!tag[x]) return; 27 put(ls,tag[x]); put(rs,tag[x]); tag[x]=0; 28 } 29 30 void build(int x,int L,int R){ 31 if (L==R){ c[x]=v[x]=1; return; } 32 int mid=(L+R)>>1; 33 build(lson); build(rson); upd(x); 34 } 35 36 void mdf(int x,int L,int R,int l,int r,int k){ 37 if (L==l && r==R){ put(x,k); return; } 38 int mid=(L+R)>>1; push(x); 39 if (r<=mid) mdf(lson,l,r,k); 40 else if (l>mid) mdf(rson,l,r,k); 41 else mdf(lson,l,mid,k),mdf(rson,mid+1,r,k); 42 upd(x); 43 } 44 45 int que(int x,int L,int R,int l,int r){ 46 if (L==l && r==R) return v[x]; 47 int mid=(L+R)>>1; push(x); 48 if (r<=mid) return que(lson,l,r); 49 else if (l>mid) return que(rson,l,r); 50 else return que(lson,l,mid)+que(rson,mid+1,r); 51 } 52 53 void Mdf(int x,int w){ 54 int k=num[py+x]+(w>0); num[py+x]+=w; 55 if (x<=n) mdf(1,1,mx,py+x-k+1,py+x-k+1,w); 56 } 57 58 int main(){ 59 freopen("number.in","r",stdin); 60 freopen("number.out","w",stdout); 61 scanf("%d%d",&n,&m); mx=(n+m)*2+1; py=n+m; build(1,1,mx); 62 rep(i,1,n) scanf("%d",&a[i]),Mdf(a[i],1); 63 while (m--){ 64 scanf("%d%d",&p,&x); 65 if (p>0) Mdf(a[p]+L,-1),a[p]=x-L,Mdf(a[p]+L,1); 66 else if (x>0){ 67 py--; L++; int pos=py+n+1; 68 if (num[pos]>0) mdf(1,1,mx,pos-num[pos]+1,pos,-1); 69 }else{ 70 int pos=py+n+1; py++; L--; 71 if (num[pos]>0) mdf(1,1,mx,pos-num[pos]+1,pos,1); 72 } 73 printf("%d ",que(1,1,mx,py+1,py+n)); 74 } 75 return 0; 76 }