"若是万一琪露诺(俗称rhl)进行攻击,什么都好,冷静地回答她的问题来吸引她。对方表现出兴趣的话,那就慢慢地反问。在她考虑答案的时候,趁机逃吧。就算是很简单的问题,她一定也答不上来。"--《上古之魔书》
天空中出现了许多的北极光,这些北极光组成了一个长度为n的正整数数列a[i],远古之魔书上记载到:2个位置的graze值为两者位置差与数值差的和:graze(x,y)=|x-y|+|a[x]-a[y]|。
要想破解天罚,就必须支持2种操作(k都是正整数):
Modify x k:将第x个数的值修改为k。
Query x k:询问有几个i满足graze(x,i)<=k。
由于从前的天罚被圣王lmc破解了,所以rhl改进了她的法术,询问不仅要考虑当前数列,还要考虑任意历史版本,
即统计任意位置上出现过的任意数值与当前的a[x]的graze值<=k的对数。(某位置多次修改为同样的数值,按多次统计)
第1行两个整数n,q。分别表示数列长度和操作数。
第2行n个正整数,代表初始数列。
第3~q+2行每行一个操作。
N<=40000, 修改操作数<=60000, 询问操作数<=10000, Max{a[i]}(含修改)<=80000
1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 #define N (1000009)
5 using namespace std;
6
7 struct Que{int x,y,opt,v;}Q[N],tmp[N];
8 int n,m,q_num,cnt,a[N],c[N],ans[N];
9 char opt[10];
10
11 inline int read()
12 {
13 int x=0,w=1; char c=getchar();
14 while (c<‘0‘ || c>‘9‘) {if (c==‘-‘) w=-1; c=getchar();}
15 while (c>=‘0‘ && c<=‘9‘) x=x*10+c-‘0‘, c=getchar();
16 return x*w;
17 }
18
19 void Update(int x,int k)
20 {
21 for (; x<=1e6; x+=(x&-x)) c[x]+=k;
22 }
23
24 int Query(int x)
25 {
26 int ans=0;
27 for (; x; x-=(x&-x)) ans+=c[x];
28 return ans;
29 }
30
31 void CDQ(int l,int r)
32 {
33 if (l==r) return;
34 int mid=(l+r)>>1;
35 CDQ(l,mid); CDQ(mid+1,r);
36 int i=l,j=mid+1,k=l-1;
37 while (i<=mid || j<=r)
38 if (j>r || i<=mid && (Q[i].x<Q[j].x || Q[i].x==Q[j].x && Q[i].opt<Q[j].opt))
39 {
40 if (Q[i].opt==1) Update(Q[i].y,1);
41 tmp[++k]=Q[i]; ++i;
42 }
43 else
44 {
45 if (Q[j].opt==2)
46 {
47 if (Q[j].v>0) ans[Q[j].v]+=Query(Q[j].y);
48 else ans[-Q[j].v]-=Query(Q[j].y);
49 }
50 tmp[++k]=Q[j]; ++j;
51 }
52 for (int i=l; i<=mid; ++i) if (Q[i].opt==1) Update(Q[i].y,-1);
53 for (int i=l; i<=r; ++i) Q[i]=tmp[i];
54 }
55
56 int main()
57 {
58 n=read(); m=read();
59 for (int i=1; i<=n; ++i)
60 {
61 a[i]=read();
62 Q[++q_num]=(Que){i+a[i],i-a[i],1,1};
63 }
64 for (int i=1; i<=m; ++i)
65 {
66 scanf("%s",opt); int x=read(),k=read();
67 if (opt[0]==‘M‘) a[x]=k, Q[++q_num]=(Que){x+k,x-k,1,1};
68 else
69 {
70 ++cnt;
71 Q[++q_num]=(Que){x+a[x]+k,x-a[x]+k,2,cnt};
72 Q[++q_num]=(Que){x+a[x]-k-1,x-a[x]-k-1,2,cnt};
73 Q[++q_num]=(Que){x+a[x]-k-1,x-a[x]+k,2,-cnt};
74 Q[++q_num]=(Que){x+a[x]+k,x-a[x]-k-1,2,-cnt};
75 }
76 }
77 for (int i=1; i<=q_num; ++i) Q[i].x+=500000, Q[i].y+=500000;
78 CDQ(1,q_num);
79 for (int i=1; i<=cnt; ++i) printf("%d\n",ans[i]);
80 }