1. 程式人生 > >BZOJ 2124 等差子序列

BZOJ 2124 等差子序列

type hash pre 線段 shu point oid 維護 size

題解:

長度定為3

線段樹維護區間hash值

從左向右處理,依次在數軸上插入處理的元素;

如果當前數軸不對稱,則缺失的那個元素一定在後面出現

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef unsigned long long uLint;
const uLint bas=233;
const int maxn=100009;

int T;
int n;
uLint fac[maxn];
int a[maxn];

struct SegmentTree{
	int l,r;
	uLint hl,hr;
}tree[maxn<<2];
void pushup(int now){
	tree[now].hl=tree[now<<1].hl*fac[tree[now<<1|1].r-tree[now<<1|1].l+1]+tree[now<<1|1].hl;
	tree[now].hr=tree[now<<1|1].hr*fac[tree[now<<1].r-tree[now<<1].l+1]+tree[now<<1].hr;
}
void BuildTree(int now,int l,int r){
	tree[now].l=l;tree[now].r=r;tree[now].hl=tree[now].hr=0;
	if(l==r)return;
	int mid=(l+r)>>1;
	BuildTree(now<<1,l,mid);
	BuildTree(now<<1|1,mid+1,r);
}
void Updatapoint(int now,int p){
	if(tree[now].l==tree[now].r){
		tree[now].hl=tree[now].hr=1;return;
	}
	int mid=(tree[now].l+tree[now].r)>>1;
	if(p<=mid)Updatapoint(now<<1,p);
	else Updatapoint(now<<1|1,p);
	pushup(now);
}
uLint Queryhash(int now,int ll,int rr,int opty){
	if(tree[now].l>=ll&&tree[now].r<=rr){
		if(opty==0)return tree[now].hl;
		else return tree[now].hr;
	}
	int mid=(tree[now].l+tree[now].r)>>1;
	uLint ret=0;
	if(opty==0){
		if(ll<=mid&&rr>mid){
			ret=Queryhash(now<<1,ll,rr,opty)*fac[min(rr-mid,tree[now].r-mid)]+Queryhash(now<<1|1,ll,rr,opty);
		}else if(ll<=mid){
			ret=Queryhash(now<<1,ll,rr,opty);
		}else{
			ret=Queryhash(now<<1|1,ll,rr,opty);
		}
	}else{
		if(ll<=mid&&rr>mid){
			ret=Queryhash(now<<1|1,ll,rr,opty)*fac[min(mid-tree[now].l,mid-ll)+1]+Queryhash(now<<1,ll,rr,opty);
		}else if(ll<=mid){
			ret=Queryhash(now<<1,ll,rr,opty);
		}else{
			ret=Queryhash(now<<1|1,ll,rr,opty);
		}
	}
	return ret;
}

int main(){
	scanf("%d",&T);
	fac[0]=1;
	for(int i=1;i<=10000;++i)fac[i]=fac[i-1]*233;
	
	while(T--){
		int fla=0;
		scanf("%d",&n);
		BuildTree(1,1,n);
		for(int i=1;i<=n;++i){
			int x;scanf("%d",&x);
			Updatapoint(1,x);
			int len=min(x,n-x+1);
			uLint tmp1=Queryhash(1,x-len+1,x,0);
			uLint tmp2=Queryhash(1,x,x+len-1,1);
			if(tmp1!=tmp2)fla=1;
		}
		if(fla)printf("Y\n");
		else printf("N\n");
	}
	return 0;
}

  

BZOJ 2124 等差子序列