首页 > 其他 > 详细

BZOJ 2124 等差子序列

时间:2018-02-20 18:15:32      阅读:40      评论:0      收藏:0      [点我收藏+]

标签: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 等差子序列

标签:type   hash   pre   线段   shu   point   oid   维护   size   

原文:https://www.cnblogs.com/zzyer/p/8455491.html

(0)
(0)
   
举报
评论 一句话评论(0
0条  
登录后才能评论!
© 2014 bubuko.com 版权所有 鲁ICP备09046678号-4
打开技术之扣,分享程序人生!
             

鲁公网安备 37021202000002号