整体二分:例题以及参考代码
Star Diamond
https://www.nitacm.com/problem_show.php?pid=23142
#include<bits/stdc++.h> using namespace std; #define mid ((l+r)/2) const int maxn=100000; int ans[3*maxn+5],tree[maxn*4+5]; struct node { int tpe,id;//tpe为1表示插入,2表示查询,3表示删除。id表示编号,来确保输出答案时有序。 int x,y,num;//num表示权值,x、y表示坐标。 int lx,rx,ly,ry;//表示查询范围。 }; void c_tree(int l,int r,int p,int x,int num) { if(l==r) { tree[p]=max(tree[p],num); if(!num)tree[p]=0; } else { if(x<=mid)c_tree(l,mid,p*2,x,num); else c_tree(mid+1,r,p*2+1,x,num); tree[p]=max(tree[p*2],tree[p*2+1]); } } int q_tree(int l,int r,int p,int L,int R) { if(l==L&&r==R)return tree[p]; else { if(R<=mid)return q_tree(l,mid,p*2,L,R); else if(L>mid)return q_tree(mid+1,r,p*2+1,L,R); else return max(q_tree(l,mid,p*2,L,mid),q_tree(mid+1,r,p*2+1,mid+1,R)); } } queue<node>q[25][2]; void all_binary(int l,int r,int dep,bool f) { if(q[dep][f].empty())return; while(!q[dep][f].empty()) { node tmp=q[dep][f].front(); q[dep][f].pop(); if(tmp.tpe==1) { c_tree(1,maxn,1,tmp.x,tmp.num); if(l!=r) { if(tmp.y<=mid)q[dep+1][0].push(tmp); else q[dep+1][1].push(tmp); } } if(tmp.tpe==2) { if(tmp.ly==l&&tmp.ry==r)ans[tmp.id]=max(ans[tmp.id],q_tree(1,maxn,1,tmp.lx,tmp.rx)); else { if(l!=r) { if(tmp.ly<=mid) { node tmp0=tmp; tmp0.ry=min(tmp0.ry,mid); q[dep+1][0].push(tmp0); } if(tmp.ry>mid) { node tmp0=tmp; tmp0.ly=max(tmp0.ly,mid+1); q[dep+1][1].push(tmp0); } } } } if(tmp.tpe==3) { c_tree(1,maxn,1,tmp.x,0); if(l!=r) { if(tmp.y<=mid)q[dep+1][0].push(tmp); else q[dep+1][1].push(tmp); } } } all_binary(l,mid,dep+1,0),all_binary(mid+1,r,dep+1,1); } vector<node>v; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { node tmp; ans[i]=-1; tmp.id=i; scanf("%d",&tmp.tpe); if(tmp.tpe==1)scanf("%d %d %d",&tmp.x,&tmp.y,&tmp.num),v.push_back(tmp); if(tmp.tpe==2)scanf("%d %d %d %d",&tmp.lx,&tmp.rx,&tmp.ly,&tmp.ry); q[0][0].push(tmp); } for(node tmp:v) { tmp.tpe=3; q[0][0].push(tmp); } all_binary(1,maxn,0,0); for(int i=1;i<=n;i++)if(ans[i]!=-1)printf("%d\n",ans[i]); return 0; }
Sound! Euphonium
https://www.nitacm.com/problem_show.php?pid=21258
#include<bits/stdc++.h> using namespace std; int i,i0,n,m,ans[100005],bit[100005],f,bac[100005]; struct node { int num,i,l,r,tpe; }tmp,tmp0; int lowbit(int t){return t&(-t);} int sum(int i) { int s=0; while(i>0)s+=bit[i],i-=lowbit(i); return s; } void add(int i,int x){while(i<=n+1)bit[i]+=x,i+=lowbit(i);} list<node>q[18][2]; void all_binary(int l,int r,int dep,bool f) { if(q[dep][f].empty())return; if(l==r) { while(!q[dep][f].empty()) { tmp=q[dep][f].front(),q[dep][f].pop_front(); if(tmp.tpe==1)ans[tmp.i]=max(ans[tmp.i],min(tmp.r-tmp.l+1-tmp.num,l)); } return; } int mid=(l+r+1)/2,tcnt; while(!q[dep][f].empty()) { tmp=q[dep][f].front(),q[dep][f].pop_front(); if(tmp.tpe==1) { tcnt=sum(tmp.r)-sum(tmp.l-1); if(tmp.r-tmp.l+1-tcnt-tmp.num<mid)q[dep+1][0].push_back(tmp); else tmp.num+=tcnt,q[dep+1][1].push_back(tmp); } if(tmp.tpe==2) { if(tmp.num<mid) { add(tmp.i,1); q[dep+1][0].push_back(tmp); } else { q[dep+1][1].push_back(tmp); } } if(tmp.tpe==3) { if(tmp.num<mid) { add(tmp.i,-1); q[dep+1][0].push_back(tmp); } else { q[dep+1][1].push_back(tmp); } } } all_binary(l,mid-1,dep+1,0); all_binary(mid,r,dep+1,1); } int main() { scanf("%d %d",&n,&m); memset(ans,-1,sizeof(ans)); tmp.tpe=2; for(i=1;i<=n;i++) { scanf("%d",&bac[i]); tmp.num=bac[i],tmp.i=i; q[0][0].push_back(tmp); } for(i=0;i<m;i++) { scanf("%d",&tmp.tpe); if(tmp.tpe==1)scanf("%d %d",&tmp.l,&tmp.r),tmp.num=0,tmp.i=i,q[0][0].push_back(tmp); if(tmp.tpe==2) { scanf("%d %d",&tmp.i,&tmp.num); tmp0.tpe=3,tmp0.i=tmp.i,tmp0.num=bac[tmp.i]; q[0][0].push_back(tmp0); q[0][0].push_back(tmp); bac[tmp.i]=tmp.num; } } tmp.tpe=3; for(i=1;i<=n;i++) { tmp.num=bac[i],tmp.i=i; q[0][0].push_back(tmp); } all_binary(1,n,0,0); for(i=0;i<m;i++)if(ans[i]!=-1)printf("%d\n",ans[i]); return 0; }