首先特判掉k=0和l=r的情况,那么剩下来的情况要成立必满足三个条件:
①区间内max-min=k*区间长,用线段树维护max和min就好了。
②区间排序后差分,gcd==k。gcd也可以用线段树维护,即差分后,gcd=gcd(左儿子gcd,右儿子gcd)(注意gcd=0是须特判)。
③区间内没有重复的值。对于每个权值开一个set,用于查询每个点的右边第一次出现和它相等的值的下标。线段树维护这些下标的min,如果查询时min大于r说明符合条件。
然而烧了一天也没搞出这题来。最后,**哥告诉我:“你被卡常了。放弃吧。”
我简直是来搞笑的。
代码:
#pragma GCC optimize("O2")
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<algorithm>
#include<set>
#include<map>
using namespace std;
#define rep(i,j,k) for(i=j;i<=k;++i)
#define per(i,j,k) for(i=j;i>=k;--i)
#define G getchar()
#define LL long long
#define pll pair<int,int>
#define mkp make_pair
#define X first
#define Y second
const int N=300005;
int n,a[N],pre[N],nxt[N],ans;
set<int>st[N<<1];map<int,int>mp;int id;
int Max[N<<2],Min[N<<2],Gcd[N<<2],Flg[N<<2],Nxt[N<<2];
int MAX,MIN,GCD,NXT;
inline void read(int &x){
char ch=G;//int f=1;
for(;ch>57||ch<48;ch=G);//if(ch==45)f=-1;
for(x=0;ch>=48&&ch<=57;ch=G)x=x*10+ch-48;
//x*=f;
}
void modify2(int x,int l,int r,int num){
if(l==r){
Nxt[num]=nxt[l];return;
}
int mid=l+r>>1;
if(x>mid)modify2(x,mid+1,r,num<<1|1);
else modify2(x,l,mid,num<<1);
Nxt[num]=min(Nxt[num<<1],Nxt[num<<1|1]);
}
inline void ins(int i){
set<int>::iterator ii;
if(mp.insert(mkp(a[i],id)).Y){
st[id].insert(nxt[i]=n+1);st[id].insert(pre[i]=0);
st[id++].insert(i);
}
else{
ii=st[mp[a[i]]].insert(i).X;
++ii;
if((nxt[i]=*ii)<=n)pre[nxt[i]]=i;
--ii;--ii;
if(pre[i]=*ii){nxt[pre[i]]=i;modify2(pre[i],1,n,1);}
}
}
inline void del(int i){
int x=mp[a[i]];
set<int>::iterator ii=st[x].lower_bound(i);
if(nxt[i]<=n)pre[nxt[i]]=pre[i];
if(pre[i]){nxt[pre[i]]=nxt[i];modify2(pre[i],1,n,1);}
st[x].erase(ii);
}
int gcd(int x,int y){
if(!x)return y;
if(!y)return x;
if(x%y==0)return y;
return gcd(y,x%y);
}
inline void up(int num){
Max[num]=max(Max[num<<1],Max[num<<1|1]);
Min[num]=min(Min[num<<1],Min[num<<1|1]);
Flg[num]=Flg[num<<1]==Flg[num<<1|1]?Flg[num<<1]:-1;
Nxt[num]=min(Nxt[num<<1],Nxt[num<<1|1]);
}
inline void up2(int num){
Gcd[num]=gcd(Gcd[num<<1],Gcd[num<<1|1]);
}
void build(int l,int r,int num){
if(l==r){
Max[num]=Min[num]=Flg[num]=a[l];
Nxt[num]=nxt[l];return;
}
int mid=l+r>>1;
build(l,mid,num<<1);build(mid+1,r,num<<1|1);
up(num);
}
void build2(int l,int r,int num){
if(l==r){
Gcd[num]=abs(a[l]-a[l+1]);
return;
}
int mid=l+r>>1;
build2(l,mid,num<<1);build2(mid+1,r,num<<1|1);
up2(num);
}
void modify(int x,int y,int l,int r,int num){
if(l==r){
del(l);
Max[num]=Min[num]=Flg[num]=a[l]=y;
ins(l);Nxt[num]=nxt[l];return;
}
int mid=l+r>>1;
if(x<=mid)modify(x,y,l,mid,num<<1);
else modify(x,y,mid+1,r,num<<1|1);
up(num);
}
void modify2(int x,int y,int l,int r,int num){
if(l==r){
Gcd[num]=y;return;
}
int mid=l+r>>1;
if(x<=mid)modify2(x,y,l,mid,num<<1);
else modify2(x,y,mid+1,r,num<<1|1);
up2(num);
}
int query1(int L,int R,int l,int r,int num){
if(L<=l&&r<=R)return Flg[num];
int mid=l+r>>1;
if(R<=mid)return query1(L,R,l,mid,num<<1);
if(L>mid)return query1(L,R,mid+1,r,num<<1|1);
int tmp=query1(L,R,l,mid,num<<1);
return tmp==query1(L,R,mid+1,r,num<<1|1)?tmp:-1;
}
int query2(int L,int R,int l,int r,int num){
if(L<=l&&r<=R){
MAX=max(MAX,Max[num]);
MIN=min(MIN,Min[num]);
NXT=min(NXT,Nxt[num]);
return Gcd[num];
}
int mid=l+r>>1;
if(R<=mid)return query2(L,R,l,mid,num<<1);
if(L>mid)return query2(L,R,mid+1,r,num<<1|1);
return gcd(query2(L,R,l,mid,num<<1),query2(L,R,mid+1,r,num<<1|1));
}
void query(int L,int R,int l,int r,int num){
if(L<=l&&r<=R){
MAX=max(MAX,Max[num]);
MIN=min(MIN,Min[num]);
NXT=min(NXT,Nxt[num]);
return;
}
int mid=l+r>>1;
if(L<=mid)query(L,R,l,mid,num<<1);
if(R>mid)query(L,R,mid+1,r,num<<1|1);
}
int main(){
// freopen("r.in","r",stdin);
// freopen("w.out","w",stdout);
int Q,i,o,x,y,k;
read(n);read(Q);
rep(i,1,n){
read(a[i]);
if(n!=1)ins(i);
}
if(n!=1)build(1,n,1),build2(1,n-1,1);
while(Q--){
read(o);read(x);read(y);x^=ans;y^=ans;
if(o==1){
if(n==1)continue;
if(x<n)modify2(x,abs(a[x+1]-y),1,n-1,1);
if(x>1)modify2(x-1,abs(a[x-1]-y),1,n-1,1);
modify(x,y,1,n,1);
}
else{
read(k);k^=ans;
if(x==y){
++ans,puts("Yes");continue;
}
if(!k){
if(query1(x,y,1,n,1)>=0)
++ans,puts("Yes");
else
puts("No");
continue;
}
MAX=0,MIN=NXT=n+1;
query(x,y,1,n,1);
GCD=query2(x,y-1,1,n-1,1);
if(GCD==k&&MAX-MIN==k*(y-x)&&NXT>y)
++ans,puts("Yes");
else puts("No");
}
}
return 0;
}