只要检查区间和与预期是否相等即可ac
其实是我的检查区间平方和式子写假了 然后6wa1mle
参考代码(当然求调我写假的区间平方和 即注释掉的两行)
#include <iostream>
#include <set>
using namespace std;
typedef long long ll;
inline ll lc(ll p){return p<<1;}
inline ll rc(ll p){return p<<1|1;}
const ll Maxn=5e5+5;
ll n,m,cnt;
ll sum[Maxn<<2],ma[Maxn<<2],mi[Maxn<<2],sqr[Maxn<<2];
ll a[Maxn];
ll mod=998244353;
ll fastpow(ll a,ll b)
{
ll res=1%mod,base=a%mod;
while(b)
{
if(b&1) res=res*base%mod;
base=base*base%mod;
b>>=1;
}
return res;
}
void pushup(ll p)
{
sum[p]=(sum[lc(p)]+sum[rc(p)])%mod;
sqr[p]=(sqr[lc(p)]+sqr[rc(p)])%mod;
ma[p]=max(ma[lc(p)],ma[rc(p)]);
mi[p]=min(mi[lc(p)],mi[rc(p)]);
}
void build(ll p,ll l,ll r)
{
if(l==r)
{
sum[p]=mi[p]=ma[p]=a[l]%mod;
sqr[p]=(a[l]*a[l])%mod;
return;
}
ll mid=(l+r)>>1;
build(lc(p),l,mid);
build(rc(p),mid+1,r);
pushup(p);
}
void modify(ll p,ll l,ll r,ll x,ll y)
{
if(l==r)
{
a[l]=y%mod;
sum[p]=mi[p]=ma[p]=a[l];
sqr[p]=(a[l]*a[l])%mod;
return;
}
ll mid=(l+r)>>1;
if(x<=mid) modify(lc(p),l,mid,x,y);
else modify(rc(p),mid+1,r,x,y);
pushup(p);
}
ll querysum(ll p,ll l,ll r,ll ql,ll qr)
{
if(ql<=l&&r<=qr) return sum[p];
ll mid=(l+r)>>1,ret=0;
if(ql<=mid) ret=querysum(lc(p),l,mid,ql,qr);
if(mid<qr) ret+=querysum(rc(p),mid+1,r,ql,qr);
return ret%mod;
}
ll querysqr(ll p,ll l,ll r,ll ql,ll qr)
{
if(ql<=l&&r<=qr) return sqr[p];
ll mid=(l+r)>>1,ret=0;
if(ql<=mid) ret=querysqr(lc(p),l,mid,ql,qr);
if(mid<qr) ret+=querysqr(rc(p),mid+1,r,ql,qr);
return ret%mod;
}
ll queryma(ll p,ll l,ll r,ll ql,ll qr)
{
if(ql<=l&&r<=qr) return ma[p];
ll mid=(l+r)>>1,ret=0;
if(ql<=mid) ret=queryma(lc(p),l,mid,ql,qr);
if(mid<qr) ret=max(ret,queryma(rc(p),mid+1,r,ql,qr));
return ret;
}
ll querymi(ll p,ll l,ll r,ll ql,ll qr)
{
if(ql<=l&&r<=qr) return mi[p];
ll mid=(l+r)>>1,ret=0x7fffffff;
if(ql<=mid) ret=querymi(lc(p),l,mid,ql,qr);
if(mid<qr) ret=min(ret,querymi(rc(p),mid+1,r,ql,qr));
return ret;
}
int inv2,inv6;
bool query(ll ql,ll qr,ll k)
{
ll Sum=querysum(1,1,n,ql,qr),Sqr=querysqr(1,1,n,ql,qr),Ma=queryma(1,1,n,ql,qr),Mi=querymi(1,1,n,ql,qr);
ll len=qr-ql+1;
if((len-1)*k!=Ma-Mi) return 0;
ll realsum=(Mi+Ma)*len%mod*inv2%mod;
if(realsum!=Sum) return 0;
// ll realsqr=(Mi*Mi%mod*len%mod+k*(len-1)%mod*len%mod+k*k%mod*(len-1)%mod*len%mod*(2*len-1)%mod*inv6%mod)%mod;
// if(realsqr!=Sqr) return 0;
return 1;
}
signed main()
{
inv2=fastpow(2,mod-2),inv6=fastpow(6,mod-2);
cin>>n>>m;
for(ll i=1;i<=n;i++) scanf("%lld",&a[i]);
build(1,1,n);
ll op,x,y,l,r,k;
for(ll i=1;i<=m;i++)
{
scanf("%lld",&op);
if(op==1)
{
scanf("%lld%lld",&x,&y);
x^=cnt,y^=cnt;
modify(1,1,n,x,y);
}
else
{
scanf("%lld%lld%lld",&l,&r,&k);
l^=cnt,r^=cnt,k^=cnt;
if(query(l,r,k))
{
printf("Yes\n");
cnt++;
}
else printf("No\n");
}
}
}