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");
    }

}
bzoj_2124

 

posted @ 2017-09-27 11:42  A_LEAF  阅读(121)  评论(0编辑  收藏  举报