[ 线段树+哈希 ] 反等差数列

分析

读入一个数$x$,如果在它之前——$x-k,x+k$中只有一个数出现过,就会出现$x-k,x,x+k$或$x+k,x,x-k$的情况。该数列不是反等差数列。

用一个$01$串表示当前所有数的出现情况。如果$i$出现过,$s[i]=1$,否则$s[i]=0$。

当前读入数为$x$,分析性质可知仅当该$01$串以$x$为中心左右对称时合法。

例:1101x1011合法,10110x011合法。

       0100x1011不合法,011x0110不合法。

所以,每读入一个数$x$,$hash$判断当前$01$串是否合法。(因为会超时,所以在线段树上操作。)

代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef unsigned int uint;
 4 const int N=2e5+5;
 5 int n,now,len[N<<2];
 6 uint hsh0,hsh1,Pow[N],hsh[2][N<<2];
 7 inline int read() {
 8     int x=0; char c=getchar();
 9     while(c<'0'||c>'9') c=getchar();
10     while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0',c=getchar();
11     return x;
12 }
13 
14 int ls(int p) {return p<<1;}
15 int rs(int p) {return p<<1|1;}
16 void build(int p,int l,int r) {
17     if(l==r) {len[p]=1; return ;}
18     int Mid=(l+r)>>1;
19     build(ls(p),l,Mid);
20     build(rs(p),Mid+1,r);
21     len[p]=len[ls(p)]+len[rs(p)];
22 }
23 void get(int p) {
24     hsh[0][p]=hsh[0][ls(p)]+hsh[0][rs(p)]*Pow[len[ls(p)]];
25     hsh[1][p]=hsh[1][ls(p)]*Pow[len[rs(p)]]+hsh[1][rs(p)];
26 }
27 void update(int x,int p,int l,int r) {
28     if(l==r) {hsh[0][p]=hsh[1][p]=1; return ;}
29     int Mid=(l+r)>>1;
30     if(x<=Mid) update(x,ls(p),l,Mid);
31     else update(x,rs(p),Mid+1,r);
32     get(p);
33 }
34 void query0(int ql,int qr,int p,int l,int r) {
35     if(ql<=l&&r<=qr) {
36         hsh0+=hsh[0][p]*Pow[now];
37         now+=len[p];
38         return ;
39     }
40     int Mid=(l+r)>>1;
41     if(ql<=Mid) query0(ql,qr,ls(p),l,Mid);
42     if(qr>Mid) query0(ql,qr,rs(p),Mid+1,r);
43 }
44 void query1(int ql,int qr,int p,int l,int r) {
45     if(ql<=l&&r<=qr) {
46         hsh1+=hsh[1][p]*Pow[now];
47         now+=len[p];
48         return ;
49     }
50     int Mid=(l+r)>>1;
51     if(qr>Mid) query1(ql,qr,rs(p),Mid+1,r);
52     if(ql<=Mid) query1(ql,qr,ls(p),l,Mid);
53 }
54 
55 int main() {
56     n=read();
57     Pow[0]=1;
58     for(int i=1;i<=n;i++) Pow[i]=Pow[i-1]*233;
59     build(1,1,n);
60     for(int i=1;i<=n;i++) {
61         int a=read();
62         update(a,1,1,n);
63         int l=min(a-1,n-a);
64         if(l) {
65             hsh0=now=0;
66             query0(a-l,a-1,1,1,n);
67             hsh1=now=0;
68             query1(a+1,a+l,1,1,n);
69             if(hsh0^hsh1) return printf("NO"),0;
70         }
71     }
72     printf("YES");
73 }

 

posted @ 2019-04-17 21:53  YeLingqi  阅读(262)  评论(0编辑  收藏  举报