darkbzoj
SOL
-
据说可以对修改二进制分组+主席树在线做? 学学吧。。。
-
先把曼达顿距离转化成切尔雪夫距离,即:
-
∣ x 1 − x 2 ∣ + ∣ y 1 − y 2 ∣ ≤ k |x_1-x_2|+|y_1-y_2|\le k ∣x1−x2∣+∣y1−y2∣≤k 转化为 m a x ( ∣ x 1 ′ − x 2 ′ ∣ , ∣ y 1 ′ − y 2 ′ ∣ ) ≤ k max(|x_1'-x_2'|,|y_1'-y_2'|)\le k max(∣x1′−x2′∣,∣y1′−y2′∣)≤k其中 x 1 ′ = x 1 + y 1 , y 1 ′ = x 1 − y 1 x_1'=x_1+y_1,y_1'=x_1-y_1 x1′=x1+y1,y1′=x1−y1
-
然后成为了带修改的二维数点,cdq分治即可
CODE
#include<bits/stdc++.h>
using namespace std;
#define sf scanf
#define pf printf
#define ll long long
#define cs const
#define db double
#define ri register int
#define gc getchar()
#define in red()
inline int red(){
int num=0,f=1;char c=gc;
for(;!isdigit(c);c=gc)if(c=='-')f=-1;
for(;isdigit(c);c=gc)num=(num<<1)+(num<<3)+(c^48);
return num*f;
}
#define lb(x) (x&(-x))
cs int N=1e6+100,mov=3e5+10,lim=6e5+30;
int sum[N];
inline void up(int k,int v){for(;k<=lim;k+=lb(k))sum[k]+=v;}
inline int qy(int k){int ans=0;for(;k;k-=lb(k))ans+=sum[k];return ans;}
struct op{
int tim,x,y,d,sy,id;
inline bool operator <(cs op &t){
return x==t.x ? d>t.d : x<t.x;
}
}q[N],tmp[N];
int top=0,ans[N],tot,n,m,a[N],cnt=0;
inline void cdq(int l,int r){
if(l==r)return;
int mid=(l+r)>>1;
cdq(l,mid);cdq(mid+1,r);
top=0;
for(ri i=l;i<=r;++i)tmp[++top]=q[i];
sort(tmp+1,tmp+top+1);
for(ri i=1;i<=top;++i){
if(tmp[i].tim<=mid&&tmp[i].d==2)up(tmp[i].y,1);
if(tmp[i].tim>mid&&tmp[i].d^2){
ans[tmp[i].id]+=tmp[i].d*(qy(tmp[i].y)-qy(tmp[i].sy-1));
}
}
for(ri i=1;i<=top;++i){
if(tmp[i].tim<=mid&&tmp[i].d==2)up(tmp[i].y,-1);
}
}
char s[20];
signed main(){
// freopen("data.in","r",stdin);
n=in;m=in;
for(ri i=1;i<=n;++i){
a[i]=in;++tot;
q[tot]=(op){tot,i+a[i]+mov,i-a[i]+mov,2,0,0};
}
while(m--){
sf("%s",s);int x=in,k=in;
if(s[0]=='M'){
a[x]=k;
++tot;q[tot]=(op){tot,x+k+mov,x-k+mov,2,0,0};
}
if(s[0]=='Q'){
++cnt;
++tot;q[tot]=(op){tot,x+a[x]-k-1+mov,x-a[x]+mov+k,-1,x-a[x]+mov-k,cnt};
++tot;q[tot]=(op){tot,x+a[x]+k+mov,x-a[x]+mov+k,1,x-a[x]+mov-k,cnt};
}
}
cdq(1,tot);
for(ri i=1;i<=cnt;++i)cout<<ans[i]<<'\n';
return 0;
}