代码源每日一题div1 蜗蜗的数列

Daimayuan Online Judge

思路:构造+差分维护
为了判断 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[i1]C[i2],其中 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=0D=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] [l2,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} Cl2,Cl1,Cl,Cl+1,Cr1,Cr,Cr+1,Cr+2Cl2,Cl1,Cl+f1,Cl+1+f2,Cr1+frl,Cr+frl+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} Dl2,Dl1,Dl,Dl+1,Dr1,Dr,Dr+1,Dr+2Dl2,Dl1,Dl+1,Dl+1,Dr1,Dr,Dr+1frl+2,Dr+2frl+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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学不会数据库

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值