这道题可以用哈希...感觉哈希真的是很万能的一种方法...
我们可以用线段树记录一下[l,r]这个区间的数的和,数的平方和,那么对于一个询问,我们算一下这个等差序列的和与平方和是否与这个区间的相等,如果相等我们就认为可以构成等差数列。
感觉这种哈希的思想很巧妙,这种思想还是要多尝试,多应用
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 #define maxn 300005 6 typedef unsigned long long ull; 7 struct tree 8 { 9 int l,r,k; 10 ull sum,psum; 11 }t[maxn*4]; 12 int n,m,cnt; 13 ull a[maxn]; 14 15 inline int read(void) 16 { 17 int x=0; 18 char ch=getchar(); 19 while (ch>'9'||ch<'0') ch=getchar(); 20 while (ch>='0'&&ch<='9') 21 { 22 x=x*10+ch-'0'; 23 ch=getchar(); 24 } 25 return x; 26 } 27 28 void build(int x,int l,int r) 29 { 30 t[x].l=l;t[x].r=r; 31 if (l==r) 32 { 33 t[x].sum=a[l]; 34 t[x].psum=a[l]*a[l]; 35 t[x].k=a[l]; 36 return; 37 } 38 int mid=(l+r)>>1; 39 build(2*x,l,mid); 40 build(2*x+1,mid+1,r); 41 t[x].k=min(t[2*x].k,t[2*x+1].k); 42 t[x].sum=t[2*x].sum+t[2*x+1].sum; 43 t[x].psum=t[2*x].psum+t[2*x+1].psum; 44 } 45 46 void change(int x,int y,int z) 47 { 48 if (t[x].l==t[x].r) 49 { 50 t[x].sum=z; 51 t[x].psum=(ull)z*z; 52 t[x].k=z; 53 return; 54 } 55 int mid=(t[x].l+t[x].r)>>1; 56 if (y<=mid) change(2*x,y,z); 57 else change(2*x+1,y,z); 58 t[x].k=min(t[2*x].k,t[2*x+1].k); 59 t[x].sum=t[2*x].sum+t[2*x+1].sum; 60 t[x].psum=t[2*x].psum+t[2*x+1].psum; 61 } 62 63 tree query(int x,int l,int r) 64 { 65 if (t[x].l==l&&t[x].r==r) return t[x]; 66 int mid=(t[x].l+t[x].r)>>1; 67 if (l>mid) return query(2*x+1,l,r); 68 else if (r<=mid) return query(2*x,l,r); 69 else 70 { 71 tree t1=query(2*x,l,mid); 72 tree t2=query(2*x+1,mid+1,r); 73 tree t3; 74 t3.k=min(t1.k,t2.k); 75 t3.sum=t1.sum+t2.sum; 76 t3.psum=t1.psum+t2.psum; 77 return t3; 78 } 79 } 80 81 int main() 82 { 83 n=read();m=read(); 84 for (int i=1;i<=n;i++) a[i]=read(); 85 build(1,1,n); 86 for (int i=1;i<=m;i++) 87 { 88 int opt=read(); 89 if (opt==1) 90 { 91 int x=read()^cnt,y=read()^cnt; 92 change(1,x,y); 93 } 94 if (opt==2) 95 { 96 int l=read()^cnt,r=read()^cnt,d=read()^cnt; 97 ull L=r-l+1; 98 tree tmp=query(1,l,r); 99 ull t1=tmp.k+(ull)(L-1)*d; 100 t1=(t1+tmp.k)*L; 101 if (t1!=tmp.sum*2) 102 { 103 puts("No"); 104 continue; 105 } 106 ull t2=(ull)L*((ull)6*(ull)(tmp.k-d)*(tmp.k+d*L)+(ull)d*d*(L+1)*(2*L+1)); 107 if (t2!=tmp.psum*6) 108 { 109 puts("No"); 110 continue; 111 } 112 puts("Yes"); 113 cnt++; 114 } 115 } 116 return 0; 117 }