题面:
给一个 1 到 N 的排列{Ai},询问是否存在 1<=p1<p2<p3<p4<p5<…<pLen<=N(Len>=3),使得 Ap1,Ap2,Ap3,…ApLen 是一个等差序列。
题解:
http://www.cnblogs.com/zyfzyf/p/3898065.html
代码:
#include<bits/stdc++.h> #define N (1<<15) #define M (l+r>>1) #define P (k<<1) #define S (k<<1|1) #define K l,r,k #define L l,M,P #define R M+1,r,S #define Z int l=0,int r=n,int k=1 using namespace std; int n; typedef unsigned long long ull; const ull base=23; ull d[N],u[N],v[N]; void update(Z){ u[k]=u[P]+u[S]*d[M-l+1]; v[k]=v[S]+v[P]*d[r-M]; } void A(int s,int t,Z){ if(l==r) u[k]=v[k]=s; else{ if(t<=M) A(s,t,L); else A(s,t,R); update(K); } } ull Q1(int s,int t,Z){ return s==l&&t==r?u[k] :t<=M?Q1(s,t,L) :s>M?Q1(s,t,R) :Q1(s,M,L) +Q1(M+1,t,R)*d[M-s+1]; } ull Q2(int s,int t,Z){ return s==l&&t==r?v[k] :t<=M?Q2(s,t,L) :s>M?Q2(s,t,R) :Q2(M+1,t,R) +Q2(s,M,L)*d[t-M]; } bool check(){ memset(u,0,sizeof u); memset(v,0,sizeof v); static int a[N]; for(int i=0;i!=n;++i) scanf("%d",a+i); for(int i=0;i!=n;++i){ if(int k=min( a[i]-1,n-a[i])) if(Q2(a[i]-k,a[i]-1) !=Q1(a[i]+1,a[i]+k)) return 1; A(1,a[i]); } return 0; } int main(){ d[0]=1; for(int i=1;i!=N;++i) d[i]=d[i-1]*base; int q; for(scanf("%d",&q);q;--q){ scanf("%d",&n); puts(check()?"Y":"N"); } }
时间: 2024-09-30 10:12:48