等差数列233。我们来以人品来做这道题,好吧。先用线段树处理,区间和,区间平方和,区间最小值之类的,这样根据询问的r、k就可以算出这些东西,再判断是否相等就好了。
是不是很有道理。
然而。。。。。。并不知道如何re了233.
贴个标称吧,貌似用的gcd之类的。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define lchild rt<<1,l,mid
#define rchild rt<<1|1,mid+1,r
#define ln rt<<1
#define rn rt<<1|1
#define GET (ch>='0'&&ch<='9')
#define MAXN 300010
using namespace std;
int n,m,cnt;
int a[MAXN];
void in(int &x)
{
char ch=getchar();x=0;
while (!GET) ch=getchar();
while (GET) x=x*10+ch-'0',ch=getchar();
}
int gcd(int a,int b) {return !b?a:gcd(b,a%b);}
int Abs(int x) {return x>0?x:-x;}
struct seg
{
int l,r,maxn,minn,Gcd,lnum,rnum;
}tree[MAXN<<2],empty;
void push_up(int rt)
{
tree[rt].lnum=tree[ln].lnum;tree[rt].rnum=tree[rn].rnum;
tree[rt].maxn=max(tree[ln].maxn,tree[rn].maxn);tree[rt].minn=min(tree[ln].minn,tree[rn].minn);
tree[rt].Gcd=gcd(gcd(tree[ln].Gcd,tree[rn].Gcd),Abs(tree[ln].rnum-tree[rn].lnum));
}
void build(int rt=1,int l=1,int r=n)
{
tree[rt].l=l;tree[rt].r=r;
if (l==r) {tree[rt].maxn=tree[rt].minn=tree[rt].lnum=tree[rt].rnum=a[l];return;}
int mid=(l+r)>>1;build(lchild);build(rchild);push_up(rt);
}
void modify(int rt,int x,int delta)
{
int L=tree[rt].l,R=tree[rt].r,mid=(L+R)>>1;
if (L==R) {tree[rt].maxn=tree[rt].minn=tree[rt].lnum=tree[rt].rnum=delta;return;}
if (x<=mid) modify(ln,x,delta);
else modify(rn,x,delta);
push_up(rt);
}
seg query(int rt,int l,int r)
{
int L=tree[rt].l,R=tree[rt].r,mid=(L+R)>>1;
if (l<=L&&r>=R) return tree[rt];
seg ret,ans1,ans2;ret=empty;
bool _l=0,_r=0;
if (l<=mid) _l=1,ans1=query(ln,l,r);
if (r>mid) _r=1,ans2=query(rn,l,r);
if (_l)
{
if (_r) ret.lnum=ans1.lnum,ret.rnum=ans2.rnum,ret.maxn=max(ans1.maxn,ans2.maxn),ret.minn=min(ans1.minn,ans2.minn),ret.Gcd=gcd(gcd(ans1.Gcd,ans2.Gcd),Abs(ans1.rnum-ans2.lnum));
else ret=ans1;
}
else ret=ans2;
return ret;
}
int main()
{
in(n);in(m);int opt,l,r,k;
for (int i=1;i<=n;i++) in(a[i]);
build();
while (m--)
{
in(opt);
if (opt==1) in(l),in(r),l^=cnt,r^=cnt,modify(1,l,r);
else
{
in(l);in(r);in(k);l^=cnt;r^=cnt;k^=cnt;if (l>r) swap(l,r);
seg t=query(1,l,r);
if ((l==r)||(t.Gcd==k&&t.maxn-t.minn==(r-l)*k)) puts("Yes"),cnt++;
else puts("No");
}
}
}