码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj2124: 等差子序列 Hash+线段树

时间:2016-05-15 21:26:21      阅读:336      评论:0      收藏:0      [点我收藏+]

标签:

题面:

给一个 1 到 N 的排列{Ai},询问是否存在 1<=p1<p2<p3<p4<p5<…<pLen<=N(Len>=3),使得 Ap1,Ap2,Ap3,…ApLen 是一个等差序列。

题解:

http://www.cnblogs.com/zyfzyf/p/3898065.html

代码:

#include<bits/stdc++.h>
#define N (1<<15)
#define M (l+r>>1)
#define P (k<<1)
#define S (k<<1|1)
#define K l,r,k
#define L l,M,P
#define R M+1,r,S
#define Z int l=0,int r=n,int k=1
using namespace std;
int n;
typedef unsigned long long ull;
const ull base=23;
ull d[N],u[N],v[N];
void update(Z){
	u[k]=u[P]+u[S]*d[M-l+1];
	v[k]=v[S]+v[P]*d[r-M];
}
void A(int s,int t,Z){
	if(l==r)
		u[k]=v[k]=s;
	else{
		if(t<=M)
			A(s,t,L);
		else
			A(s,t,R);
		update(K);
	}
}
ull Q1(int s,int t,Z){
	return s==l&&t==r?u[k]
	:t<=M?Q1(s,t,L)
	:s>M?Q1(s,t,R)
	:Q1(s,M,L)
	+Q1(M+1,t,R)*d[M-s+1];
}
ull Q2(int s,int t,Z){
	return s==l&&t==r?v[k]
	:t<=M?Q2(s,t,L)
	:s>M?Q2(s,t,R)
	:Q2(M+1,t,R)
	+Q2(s,M,L)*d[t-M];
}
bool check(){
	memset(u,0,sizeof u);
	memset(v,0,sizeof v);
	static int a[N];
	for(int i=0;i!=n;++i)
		scanf("%d",a+i);
	for(int i=0;i!=n;++i){
		if(int k=min(
		a[i]-1,n-a[i]))
			if(Q2(a[i]-k,a[i]-1)
			 !=Q1(a[i]+1,a[i]+k))
				return 1;
		A(1,a[i]);
	}
	return 0;
}
int main(){
	d[0]=1;
	for(int i=1;i!=N;++i)
		d[i]=d[i-1]*base;
	int q;
	for(scanf("%d",&q);q;--q){
		scanf("%d",&n);
		puts(check()?"Y":"N");
	}
}

  

bzoj2124: 等差子序列 Hash+线段树

标签:

原文地址:http://www.cnblogs.com/f321dd/p/5495986.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!