对于一段l至r的等差序列,一定会满足
①任意两数间的差定为k的倍数,即是相邻两数差的绝对值的最小公因数=k
②Max-min=(r-l)*k
③无相同元素
那么可以直接用线段树进行维护,并注意l==r的情况
#include <cstdio>
#include <algorithm>
#define lson (num<<1)
#define rson (lson+1)
using namespace std;
int n,m;
int a[300002];
struct WXY{
int mi,ma,s;
int ls,rs;
int l,r;
void clear()
{
mi=ma=s=ls=rs=l=r=0;
}
}tree[2500002];
inline int gcd(int x,int y)
{
if(x==0)
return y;
else if(y==0)
return x;
int m=x%y;
while(m!=0)
{
x=y;
y=m;
m=x%y;
}
return y;
}
inline int absx(int x)
{
if(x<0)
x=-x;
return x;
}
void updata(int num)
{
tree[num].ls=tree[lson].ls;
tree[num].rs=tree[rson].rs;
int ab=absx(tree[lson].rs-tree[rson].ls);
tree[num].s=gcd(gcd(tree[lson].s,tree[rson].s),ab);
tree[num].ma=max(tree[lson].ma,tree[rson].ma);
tree[num].mi=min(tree[lson].mi,tree[rson].mi);
}
void build_tree(int l,int r,int num)
{
tree[num].l=l;
tree[num].r=r;
if (l==r)
{
tree[num].ls=a[l];
tree[num].rs=a[l];
tree[num].ma=a[l];
tree[num].mi=a[l];
return;
}
int mid=(l+r)/2;
build_tree(l,mid,lson);
build_tree(mid+1,r,rson);
updata(num);
}
void change(int num,int l,int r,int x)
{
if (l<=tree[num].l&&tree[num].r<=r)
{
tree[num].ls=x;
tree[num].rs=x;
tree[num].ma=x;
tree[num].mi=x;
return;
}
else
{
int mid=(tree[num].l+tree[num].r)/2;
if (l<=mid)
change(lson,l,r,x);
if (r>mid)
change(rson,l,r,x);
updata(num);
}
}
WXY ask(int num,int l,int r)
{
if (l<=tree[num].l&&tree[num].r<=r) return tree[num];
else
{
int mid=(tree[num].l+tree[num].r)/2;
WXY ans;
ans.clear();
WXY ans1,ans2;
bool f1=false;bool f2=false;
if (l<=mid)
{
f1=true;
ans1=ask(lson,l,r);
}
if (r>mid)
{
f2=true;
ans2=ask(rson,l,r);
}
if (f1)
{
if (f2)
{
int xx=absx(ans1.rs-ans2.ls);
ans.s=gcd(gcd(ans1.s,ans2.s),xx);
ans.ma=max(ans1.ma,ans2.ma);
ans.mi=min(ans1.mi,ans2.mi);
ans.ls=ans1.ls;
ans.rs=ans2.rs;
}
else ans=ans1;
}
else ans=ans2;
return ans;
}
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
build_tree(1,n,1);
int ye=0;
for (int i=1;i<=m;i++)
{
int op=0;int x,y;
scanf("%d",&op);
if (op==1)
{
scanf("%d%d",&x,&y);
x=x^ye;
y=y^ye;
change(1,x,x,y);
}
else
{
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
l=l^ye;
r=r^ye;
k=k^ye;
WXY xt=ask(1,l,r);
if (xt.s==k&&(xt.ma-xt.mi)==k*(r-l)||l==r)
{
printf("Yes\n");
ye++;
}
else printf("No\n");
}
}
return 0;
}