题解:P10633 BZOJ2989 数列/BZOJ4170 极光
这道题实际上就是维护一个平面直角坐标系,每次加一个点,求与一个点曼哈顿距离
trick:
二维线段树即可,即外层区间线段树,内层动态开点权值线段树。
int n,m,a[N],rt[V<<2];
#define mid (l+r>>1)
struct SGT1 {
int num,ls[V<<7],rs[V<<7],val[V<<7],cnt;
void upd(int &id,int l,int r,int x) {if(!id) id=++num; val[id]++; if(l==r) return; x<=mid?upd(ls[id],l,mid,x):upd(rs[id],mid+1,r,x);}
int qry(int id,int l,int r,int L,int R) {return !id?0:L<=l&&r<=R?val[id]:(L<=mid?qry(ls[id],l,mid,L,R):0)+(R>mid?qry(rs[id],mid+1,r,L,R):0);}
}S;
struct SGT2 {
#define ls (id<<1)
#define rs (id<<1|1)
void upd(int id,int l,int r,int x,int y) {S.upd(rt[id],-V,V,y); if(l==r) return; x<=mid?upd(ls,l,mid,x,y):upd(rs,mid+1,r,x,y);}
int qry(int id,int l,int r,int L,int R,int _L,int _R) {return L<=l&&r<=R?S.qry(rt[id],-V,V,_L,_R):(L<=mid?qry(ls,l,mid,L,R,_L,_R):0)+(R>mid?qry(rs,mid+1,r,L,R,_L,_R):0);}
}T;
void QwQ() {
n=rd(),m=rd(); for(int i=1;i<=n;i++) a[i]=rd(),T.upd(1,1,V,a[i]+i,a[i]-i);
for(int x,y;m--;) {
string s; cin>>s,x=rd(),y=rd();
if(s=="Modify") a[x]=y,T.upd(1,1,V,y+x,y-x);
else wr(T.qry(1,1,V,a[x]+x-y,a[x]+x+y,a[x]-x-y,a[x]-x+y),"\n");
}
}