用一种类似于hash的做法(就是比较假可能会被卡的做法),维护区间最小值、最大值和区间和,根据这些信息来判断是否矛盾即可
当然还有比较严谨的方法,维护区间min、区间max、区间相邻两数的gcd和区间pre的max,这样就可以保证答案的正确性
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 300005 4 #define L (k<<1) 5 #define R (L+1) 6 #define mid (l+r>>1) 7 #define ll long long 8 struct ji{ 9 int mi,ma; 10 ll sum; 11 }o,k,f[N<<3]; 12 int n,m,p,x,y,z,ans; 13 ji up(ji x,ji y){ 14 ji z; 15 z.mi=min(x.mi,y.mi); 16 z.ma=max(x.ma,y.ma); 17 z.sum=x.sum+y.sum; 18 return z; 19 } 20 void update(int k,int l,int r,int x,int y){ 21 if (l==r){ 22 f[k].mi=f[k].ma=f[k].sum=y; 23 return; 24 } 25 if (x<=mid)update(L,l,mid,x,y); 26 else update(R,mid+1,r,x,y); 27 f[k]=up(f[L],f[R]); 28 } 29 ji query(int k,int l,int r,int x,int y){ 30 if ((l>y)||(x>r))return o; 31 if ((x<=l)&&(r<=y))return f[k]; 32 return up(query(L,l,mid,x,y),query(R,mid+1,r,x,y)); 33 } 34 int main(){ 35 scanf("%d%d",&n,&m); 36 o.mi=0x3f3f3f3f; 37 for(int i=1;i<=n;i++){ 38 scanf("%d",&x); 39 update(1,1,n,i,x); 40 } 41 for(int i=1;i<=m;i++){ 42 scanf("%d%d%d",&p,&x,&y); 43 x^=ans; 44 y^=ans; 45 if (p==1)update(1,1,n,x,y); 46 else{ 47 scanf("%d",&z); 48 z^=ans; 49 k=query(1,1,n,x,y); 50 bool flag=0; 51 if (1LL*z*(y-x)!=k.ma-k.mi)flag=1; 52 if ((k.mi+k.ma)*(y-x+1LL)/2!=k.sum)flag=1; 53 if (flag)printf("No\n"); 54 else{ 55 printf("Yes\n"); 56 ans++; 57 } 58 } 59 } 60 }