Bzoj2124 等差子序列
线段树维护hash值(记得传L,R的时候不能像平常一样传),wq用bitset水了...
#include <cstdio> #include <cstring> #include <iostream> #include <cstdlib> #include <algorithm> #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) #define ull unsigned long long using namespace std; const int N=10006; const int p=1000000007; int T; int n; int v[N]; ull P[N]; ull a1[N*7],a2[N*7]; void pushup(int l,int r,int x) { int mid=(l+r)>>1; a1[x]=a1[x<<1]*P[r-mid]+a1[x<<1|1]; a2[x]=a2[x<<1]+a2[x<<1|1]*P[mid-l+1]; } void add(int pos,int l,int r,int x) { if(l==r) { a1[x]=a2[x]=p; return ; } int mid=(l+r)>>1; if(pos<=mid) add(pos,l,mid,x<<1); else add(pos,mid+1,r,x<<1|1); pushup(l,r,x); } ull qq1(int L,int R,int l,int r,int x) { //printf("qq1 L=%d R=%d l=%d r=%d x=%d\n",L,R,l,r,x); if(L>R) return 0; if(L<=l&&r<=R) return a1[x]; int mid=(l+r)>>1; if(R<=mid) return qq1(L,R,l,mid,x<<1); else if(L>mid) return qq1(L,R,mid+1,r,x<<1|1); return qq1(L,mid,l,mid,x<<1)*P[R-mid]+qq1(mid+1,R,mid+1,r,x<<1|1); // is_right //return qq1(L,R,l,mid,x<<1)*P[R-mid]+qq1(L,R,mid+1,r,x<<1|1); // is_wrong //原因:计算的时候需要用到 L 和 R // 就因为这个我快炸了.... } ull qq2(int L,int R,int l,int r,int x) { //printf("qq2 L=%d R=%d l=%d r=%d x=%d\n",L,R,l,r,x); if(L>R) return 0; if(L<=l&&r<=R) return a2[x]; int mid=(l+r)>>1; if(R<=mid) return qq2(L,R,l,mid,x<<1); else if(L>mid) return qq2(L,R,mid+1,r,x<<1|1); return qq2(L,mid,l,mid,x<<1)+qq2(mid+1,R,mid+1,r,x<<1|1)*P[mid-L+1];// is_right //return qq2(L,R,l,mid,x<<1)+qq2(L,R,mid+1,r,x<<1|1)*P[mid-L+1]; // _is_wrong } int work() { mem(a1,0);mem(a2,0); int temp; ull temp1,temp2; for(int i=1;i<=n;++i) { temp=min( n-v[i],v[i]-1 ); //temp1=qq1(v[i]-temp,v[i]-1,1,n,1);temp2=qq2(v[i]+1,v[i]+temp,1,n,1); //printf("i=%d",i); //cout<<temp1<<' '<<temp2<<endl; if( temp!=0&&qq1(v[i]-temp,v[i]-1,1,n,1)!=qq2(v[i]+1,v[i]+temp,1,n,1) ) return 1; add(v[i],1,n,1); } return 0; } int main(){ freopen("sequence1.in","r",stdin); freopen("H.out","w",stdout); P[0]=1; for(int i=1;i<N;++i) P[i]=P[i-1]*p; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&v[i]); if(work()) printf("Y\n"); else printf("N\n"); } }