思路:构造+差分维护
为了判断
A
A
A,
B
B
B是否相等,我们可以构造
C
[
i
]
=
A
[
i
]
−
B
[
i
]
C[i]=A[i]-B[i]
C[i]=A[i]−B[i],问题转化为判断
C
=
0
C=0
C=0
由于差分可以维护区间加,我们自然可以想到维护一个
D
[
i
]
=
C
[
i
]
−
C
[
i
−
1
]
−
C
[
i
−
2
]
D[i]=C[i]-C[i-1]-C[i-2]
D[i]=C[i]−C[i−1]−C[i−2],其中
D
[
1
]
=
C
[
1
]
,
D
[
2
]
=
C
[
2
]
−
C
[
1
]
D[1]=C[1],D[2]=C[2]-C[1]
D[1]=C[1],D[2]=C[2]−C[1]
现在我们考虑
C
,
D
C,D
C,D之间的关系,显然
C
=
0
⇔
D
=
0
C=0\Leftrightarrow D=0
C=0⇔D=0,因此我们现在只需要判断
D
=
0
D=0
D=0即可
接下来我们来看一下对区间
[
l
,
r
]
[l,r]
[l,r]进行斐波那契加操作前后
C
,
D
C,D
C,D的变化,显然我们要看区间
[
l
−
2
,
r
+
2
]
[l-2,r+2]
[l−2,r+2]的变化
C
C
C的变化:
C
l
−
2
,
C
l
−
1
,
C
l
,
C
l
+
1
⋅
⋅
⋅
⋅
⋅
⋅
,
C
r
−
1
,
C
r
,
C
r
+
1
,
C
r
+
2
⇒
C
l
−
2
,
C
l
−
1
,
C
l
+
f
1
,
C
l
+
1
+
f
2
⋅
⋅
⋅
⋅
⋅
⋅
,
C
r
−
1
+
f
r
−
l
,
C
r
+
f
r
−
l
+
1
,
C
r
+
1
,
C
r
+
2
C_{l-2},C_{l-1},C_{l},C_{l+1}······,C_{r-1},C_{r},C_{r+1},C_{r+2}\\ \Rightarrow C_{l-2},C_{l-1},C_{l}+f_1,C_{l+1}+f_2······,C_{r-1}+f_{r-l},C_{r}+f_{r-l+1},C_{r+1},C_{r+2}
Cl−2,Cl−1,Cl,Cl+1⋅⋅⋅⋅⋅⋅,Cr−1,Cr,Cr+1,Cr+2⇒Cl−2,Cl−1,Cl+f1,Cl+1+f2⋅⋅⋅⋅⋅⋅,Cr−1+fr−l,Cr+fr−l+1,Cr+1,Cr+2
因此
D
D
D的变化为:
D
l
−
2
,
D
l
−
1
,
D
l
,
D
l
+
1
⋅
⋅
⋅
⋅
⋅
⋅
,
D
r
−
1
,
D
r
,
D
r
+
1
,
D
r
+
2
⇒
D
l
−
2
,
D
l
−
1
,
D
l
+
1
,
D
l
+
1
⋅
⋅
⋅
⋅
⋅
⋅
,
D
r
−
1
,
D
r
,
D
r
+
1
−
f
r
−
l
+
2
,
D
r
+
2
−
f
r
−
l
+
1
D_{l-2},D_{l-1},D_{l},D_{l+1}······,D_{r-1},D_{r},D_{r+1},D_{r+2}\\ \Rightarrow D_{l-2},D_{l-1},D_{l}+1,D_{l+1}······,D_{r-1},D_{r},D_{r+1}-f_{r-l+2},D_{r+2}-f_{r-l+1}
Dl−2,Dl−1,Dl,Dl+1⋅⋅⋅⋅⋅⋅,Dr−1,Dr,Dr+1,Dr+2⇒Dl−2,Dl−1,Dl+1,Dl+1⋅⋅⋅⋅⋅⋅,Dr−1,Dr,Dr+1−fr−l+2,Dr+2−fr−l+1
我们可以发现对于
D
D
D,只有
D
l
,
D
r
+
1
,
D
r
+
2
D_l,D_{r+1},D_{r+2}
Dl,Dr+1,Dr+2发生了变化,那我们只需要单独更新
D
D
D的信息,判断每次操作前后
D
p
o
s
=
0
D_{pos}=0
Dpos=0是否发生变化即可,这是对
A
A
A进行斐波那契加,对
B
B
B进行斐波那契加时,加减互换即可
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define endl '\n';
typedef long long ll;
typedef pair<int,int> PII;
const int N=1e6+10;
int n,q,mod,a[N],b[N],c[N],d[N],f[N],ans;
void update(int pos,int x){
if(pos>=1&&pos<=n){
if(d[pos]==0) ans--;
d[pos]=(d[pos]+x)%mod;
if(d[pos]==0) ans++;
}
}
int main(){
IOS;
cin>>n>>q>>mod;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
for(int i=1;i<=n;i++) c[i]=(a[i]-b[i])%mod;
d[1]=c[1],d[2]=(c[2]-c[1]+mod)%mod;
for(int i=3;i<=n;i++) d[i]=(c[i]-c[i-1]-c[i-2]+mod)%mod;
f[1]=1,f[2]=1;
for(int i=3;i<=n;i++) f[i]=(f[i-1]+f[i-2])%mod;
for(int i=1;i<=n;i++) {
if(d[i]==0) ans++;
}
while(q--){
char op;cin>>op;
int l,r;cin>>l>>r;
if(op=='A'){
update(l,1);
update(r+1,-f[r-l+2]);
update(r+2,-f[r-l+1]);
}
else{
update(l,-1);
update(r+1,f[r-l+2]);
update(r+2,f[r-l+1]);
}
if(ans==n){
cout<<"Yes"<<endl;
}else{
cout<<"No"<<endl;
}
}
return 0;
}