BZOJ2124:等差子序列(线段树,hash)
Description
给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<…<pLen<=N (Len>=3),
使得Ap1,Ap2,Ap3,…ApLen是一个等差序列。
Input
输入的第一行包含一个整数T,表示组数。
下接T组数据,每组第一行一个整数N,每组第二行为一个1到N的排列,数字两两之间用空格隔开。
N<=10000,T<=7
Output
对于每组数据,如果存在一个等差子序列,则输出一行“Y”,否则输出一行“N”。
Sample Input
2
3
1 3 2
3
3 2 1
3
1 3 2
3
3 2 1
Sample Output
N
Y
Solution
发现只用求是否存在长度为$3$的等差子序列就够了。
对于一个$a_i$,若$a_i-k$和$a_i+k$都在他前面出现才不会有$(a_i-k,a_i,a_i+k)$这个等差子序列出现。
所以可以从前往后枚举,出现为$1$未出现为$0$。可以用线段树维护区间$hash$判断以$a_i$为中心是否回文。
Code
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define N (10009) 5 #define LL unsigned long long 6 using namespace std; 7 8 int T,n,flag,a[N]; 9 LL Segt[N<<2][2],base[N]; 10 11 inline int read() 12 { 13 int x=0,w=1; char c=getchar(); 14 while (c<'0' || c>'9') {if (c=='-') w=-1; c=getchar();} 15 while (c>='0' && c<='9') x=x*10+c-'0', c=getchar(); 16 return x*w; 17 } 18 19 void Update(int now,int l,int r,int x) 20 { 21 if (l==r) {Segt[now][0]=Segt[now][1]=1; return;} 22 int mid=(l+r)>>1; 23 if (x<=mid) Update(now<<1,l,mid,x); 24 else Update(now<<1|1,mid+1,r,x); 25 Segt[now][0]=Segt[now<<1][0]*base[r-mid]+Segt[now<<1|1][0]; 26 Segt[now][1]=Segt[now<<1|1][1]*base[mid-l+1]+Segt[now<<1][1]; 27 } 28 29 LL Query(int now,int l,int r,int l1,int r1,int d) 30 { 31 if (l1<=l && r<=r1) return Segt[now][d]; 32 int mid=(l+r)>>1; 33 if (r1<=mid) return Query(now<<1,l,mid,l1,r1,d); 34 else if (l1>mid) return Query(now<<1|1,mid+1,r,l1,r1,d); 35 else if(d==0) return Query(now<<1,l,mid,l1,mid,d)*base[r1-mid]+Query(now<<1|1,mid+1,r,mid+1,r1,d); 36 else if(d==1) return Query(now<<1|1,mid+1,r,mid+1,r1,d)*base[mid-l1+1]+Query(now<<1,l,mid,l1,mid,d); 37 } 38 39 void Solve(int x) 40 { 41 Update(1,1,n,x); 42 if (x==1 || x==n) return; 43 int L=min(x-1,n-x); 44 LL lh=Query(1,1,n,x-L,x-1,0); 45 LL rh=Query(1,1,n,x+1,x+L,1); 46 if (lh!=rh) flag=1; 47 } 48 49 int main() 50 { 51 T=read(); 52 base[0]=1; 53 for (int i=1; i<=10000; ++i) base[i]=base[i-1]*1007; 54 while (T--) 55 { 56 memset(Segt,0,sizeof(Segt)); 57 n=read(); flag=0; 58 for (int i=1; i<=n; ++i) 59 { 60 int x=read(); 61 if (!flag) Solve(x); 62 } 63 puts(flag?"Y":"N"); 64 } 65 }