这道题可以用哈希...感觉哈希真的是很万能的一种方法...

我们可以用线段树记录一下[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 }

 

posted on 2017-05-24 17:30  Vergil_LY  阅读(268)  评论(0编辑  收藏  举报