Code:
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#define ll long long
using namespace std;
namespace IO {
#define rint register int
void setIO(string s) {
string in=s+".in",out=s+".out";
freopen(in.c_str(),"r",stdin);
freopen(out.c_str(),"w",stdout);
}
inline int read(){
rint x=0,f=1;char ch=getchar();
while (ch<'0' || ch>'9'){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch && ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x*f;
}
};
const int maxn=300006;
const int inf=1000000002;
int n,m;
int arr[maxn],brr[maxn];
int GCD(int a,int b) {
return b?GCD(b,a%b):a;
}
namespace A {
int minv[maxn<<2],maxv[maxn<<2];
void pushup(int l,int r,int now) {
int mid=(l+r)>>1;
minv[now]=minv[now<<1];
maxv[now]=maxv[now<<1];
if(r>mid) {
minv[now]=min(minv[now],minv[now<<1|1]);
maxv[now]=max(maxv[now],maxv[now<<1|1]);
}
}
void build(int l,int r,int now) {
if(l==r) {
minv[now]=maxv[now]=arr[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,now<<1);
if(r>mid) build(mid+1,r,now<<1|1);
pushup(l,r,now);
}
void update(int l,int r,int now,int p,int v) {
if(l==r) {
minv[now]=maxv[now]=v;
return;
}
int mid=(l+r)>>1;
if(p<=mid) update(l,mid,now<<1,p,v);
else update(mid+1,r,now<<1|1,p,v);
pushup(l,r,now);
}
int qmax(int l,int r,int now,int L,int R) {
if(l>=L&&r<=R) return maxv[now];
int mid=(l+r)>>1,re=0;
if(mid>=L) re=max(re,qmax(l,mid,now<<1,L,R));
if(R>mid) re=max(re,qmax(mid+1,r,now<<1|1,L,R));
return re;
}
int qmin(int l,int r,int now,int L,int R) {
if(l>=L&&r<=R) return minv[now];
int mid=(l+r)>>1,re=inf;
if(mid>=L) re=min(re,qmin(l,mid,now<<1,L,R));
if(R>mid) re=min(re,qmin(mid+1,r,now<<1|1,L,R));
return re;
}
};
namespace lst {
int id;
int lst[maxn<<2];
map<int,int>idx;
set<int>S[maxn<<1];
set<int>::iterator it;
void insert(int v,int i) {
if(!idx[v]) idx[v]=++id;
int cur=idx[v];
S[cur].insert(i);
}
void pushup(int l,int r,int now) {
int mid=(l+r)>>1;
lst[now]=lst[now<<1];
if(r>mid) lst[now]=max(lst[now],lst[now<<1|1]);
}
void build(int l,int r,int now) {
if(l==r) {
int cur=idx[arr[l]];
it=S[cur].lower_bound(l);
if(it==S[cur].begin()) lst[now]=-inf;
else {
it--;
lst[now]=(*it);
}
return;
}
int mid=(l+r)>>1;
if(l<=mid) build(l,mid,now<<1);
if(r>mid) build(mid+1,r,now<<1|1);
pushup(l,r,now);
}
void update(int l,int r,int now,int p) {
if(l==r) {
int cur=idx[arr[l]];
it=S[cur].lower_bound(l);
if(it==S[cur].begin()) lst[now]=-inf;
else {
it--;
lst[now]=(*it);
}
return;
}
int mid=(l+r)>>1;
if(p<=mid) update(l,mid,now<<1,p);
else update(mid+1,r,now<<1|1,p);
pushup(l,r,now);
}
int query(int l,int r,int now,int L,int R) {
if(l>=L&&r<=R) return lst[now];
int mid=(l+r)>>1,re=0;
if(L<=mid) re=max(re, query(l,mid,now<<1,L,R));
if(R>mid) re=max(re, query(mid+1,r,now<<1|1,L,R));
return re;
}
void modify(int v,int i) {
if(!idx[v]) idx[v]=++id;
int cur=idx[v];
S[idx[arr[i]]].erase(i);
it=S[idx[arr[i]]].lower_bound(i+1);
if(it!=S[idx[arr[i]]].end()) {
update(1,n,1,(*it));
}
S[cur].insert(i), arr[i]=v;
update(1,n,1,i);
}
};
namespace delta {
int gc[maxn<<2];
void pushup(int l,int r,int now) {
int mid=(l+r)>>1;
gc[now]=gc[now<<1];
if(r>mid) gc[now]=GCD(gc[now<<1|1],gc[now]);
}
void build(int l,int r,int now) {
if(l==r) {
gc[now]=brr[l];
return;
}
int mid=(l+r)>>1;
if(l<=mid) build(l,mid,now<<1);
if(r>mid) build(mid+1,r,now<<1|1);
pushup(l,r,now);
}
void update(int l,int r,int now,int p,int v) {
if(l==r) {
gc[now]=v;
return;
}
int mid=(l+r)>>1;
if(p<=mid) update(l,mid,now<<1,p,v);
else update(mid+1,r,now<<1|1,p,v);
pushup(l,r,now);
}
int query(int l,int r,int now,int L,int R) {
if(l>=L&&r<=R) return gc[now];
int mid=(l+r)>>1,re=0;
if(L<=mid) re=query(l,mid,now<<1,L,R);
if(R>mid) re=re?GCD(re,query(mid+1,r,now<<1|1,L,R)):query(mid+1,r,now<<1|1,L,R);
return re;
}
};
int main() {
using namespace IO;
// IO::setIO("input");
int i,j;
n=read(),m=read();
for(i=1;i<=n;++i) {
arr[i]=read();
lst::insert(arr[i],i);
}
for(i=1;i<=n;++i) brr[i]=abs(arr[i+1]-arr[i]);
A::build(1,n,1);
delta::build(1,n-1,1);
lst::build(1,n,1);
int cc=0;
int h=0;
for(int cas=1;cas<=m;++cas) {
int op=read();
if(op==1) {
int x,y;
x=read(),y=read(),x^=cc,y^=cc;
if(arr[x]==y) continue;
lst::modify(y,x);
A::update(1,n,1,x,y);
if(x==1) delta::update(1,n-1,1,1,abs(arr[2]-arr[1]));
else if(x==n) delta::update(1,n-1,1,n-1,abs(arr[n]-arr[n-1]));
else {
delta::update(1,n-1,1,x-1,abs(arr[x]-arr[x-1]));
delta::update(1,n-1,1,x,abs(arr[x+1]-arr[x]));
}
}
if(op==2) {
int l,r,k;
l=read(),r=read(),k=read();
l^=cc,r^=cc,k^=cc;
if(l==r) printf("Yes\n"),++cc;
else if(k==0) {
if(A::qmin(1,n,1,l,r)==A::qmax(1,n,1,l,r)) printf("Yes\n"),++cc;
else printf("No\n");
}
else {
int len=r-l;
int minn=A::qmin(1,n,1,l,r), maxx=A::qmax(1,n,1,l,r);
int flag=0;
if(maxx-minn==1ll*k*len) {
if(lst::query(1,n,1,l,r)>=l) flag=1;
else {
if(delta::query(1,n-1,1,l,r-1)%k) flag=1;
else {
printf("Yes\n"), ++cc;
}
}
}
else flag=1;
if(flag) printf("No\n");
}
}
}
return 0;
}