等差子序列

等差子序列

等差序列只要找三个数就行

x,y,z

想法枚举中间数y O(n) , 公差 d O(n) 看看y-d和y+d是不是在y的同侧(预处理每个数的pos)

这样就O (n^2) 了

优化枚举d的复杂度

我们可以搞个0/1数组,在y左边的设为1,右边的设为0

然后我们查以 y 为中心的是不是个回文串(是回文串说明找不到等差序列)

然后回文就从y向左和向右存两个hash判断是否一样

01数组存正的和反的两个hash,然后单点修改——线段树维护hash

合并 hash[ls]*base^len(rs)+hash[rs]

提醒——base 要预处理出来,开long long, 反着的hash维护注意

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define int long long
#define mid ((l+r)>>1)
#define ls (p<<1)
#define rs (p<<1|1)

inline int read(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}
const int N=40005;
const int mod=2147483647;
int T,n,a[N],len;
int hash1[N],hash2[N];
int base[N];

void merge(int p,int len) {
    int m=len>>1;
    hash1[p]=(hash1[ls]*base[m]+hash1[rs])%mod;
    hash2[p]=(hash2[ls]+hash2[rs]*base[len-m])%mod;
}

void modify(int l,int r,int v,int p) {
    if(l==r) {hash1[p]=hash2[p]=1;return;}
    if(v<=mid) modify(l,mid,v,ls);
    if(v>mid) modify(mid+1,r,v,rs);
    merge(p,r-l+1);
}

int query1(int L,int R,int l,int r,int p) {
    if(L>R) return 0;
    if(L==l&&r==R) return hash1[p];
    if(R<=mid) return query1(L,R,l,mid,ls);
    else if(L>mid) return query1(L,R,mid+1,r,rs);
    else return (query1(L,mid,l,mid,ls)*base[R-mid]+query1(mid+1,R,mid+1,r,rs))%mod;
}
int query2(int L,int R,int l,int r,int p) {
    if(L>R) return 0;
    if(L==l&&r==R) return hash2[p];
    if(R<=mid) return query2(L,R,l,mid,ls);
    else if(L>mid) return query2(L,R,mid+1,r,rs);
    else return (query2(L,mid,l,mid,ls)+query2(mid+1,R,mid+1,r,rs)*base[mid-L+1])%mod;
}

void clear() {
    memset(hash1,0,sizeof(hash1));
    memset(hash2,0,sizeof(hash2));
}
signed main() {
    T=read();
    base[1]=3;
    for(int i=2;i<=10000;i++) base[i]=(base[i-1]*3)%mod;
    while(T--) {
        clear();
        n=read();
        for(int i=1;i<=n;i++) a[i]=read();
        bool flag=0;
        for(int i=1;i<=n;i++) {
            len=min(a[i]-1,n-a[i]);
            if(query1(a[i]-len,a[i]-1,1,n,1)!=query2(a[i]+1,a[i]+len,1,n,1)) {
                flag=1;break;
            }
            modify(1,n,a[i],1);
        }
        puts(flag?"Y":"N");
    }
    return 0;
}

啊另解https://www.luogu.com.cn/user/56672

posted @ 2020-08-19 19:50  ke_xin  阅读(130)  评论(0编辑  收藏  举报