zoukankan      html  css  js  c++  java
  • 【BZOJ2124】等差子序列 树状数组维护hash值

    【BZOJ2124】等差子序列

    Description

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

    Input

    输入的第一行包含一个整数T,表示组数。
    下接T组数据,每组第一行一个整数N,每组第二行为一个1到N的排列,数字两两之间用空格隔开。
    N<=10000,T<=7

    Output

    对于每组数据,如果存在一个等差子序列,则输出一行“Y”,否则输出一行“N”。

    Sample Input

    2
    3
    1 3 2
    3
    3 2 1

    Sample Output

    N
    Y

    题解:显然我们只要让len=3就行。考虑枚举中间数,用桶维护之前已经出现过的数。我们将桶看成一个01串,如果当前数是v[i],考虑桶中v[i]左右两边的串。如果存在v[i]-j和v[i]+j在桶中的存在情况不同,则表明找到了一个等差子序列。即,如果不存在等差子序列,则桶中v[i]的左右两边一定是对称的。用树状数组维护桶的正反hash值即可。

    我才不会告诉你这题直接用bitset就能过呢~

     

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    typedef long long ll;
    const ll P=1000000009;
    const int maxn=10010;
    int n;
    int v[maxn];
    ll bs[maxn];
    struct node
    {
    	ll s[maxn];
    	inline void updata(int x,ll val)
    	{
    		for(int i=x;i<=n;i+=i&-i)	s[i]=(s[i]+val)%P;
    	}
    	inline ll query(int x)
    	{
    		ll ret=0;
    		for(int i=x;i;i-=i&-i)	ret=(ret+s[i])%P;
    		return ret;
    	}
    }s1,s2;
    inline int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')	f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret*f;
    }
    void work()
    {
    	n=rd();
    	int i,a;
    	for(i=1;i<=n;i++)	v[i]=rd();
    	memset(s1.s,0,sizeof(s1.s)),memset(s2.s,0,sizeof(s2.s));
    	for(bs[0]=1,i=1;i<=n;i++)	bs[i]=bs[i-1]*131%P;
    	for(i=1;i<=n;i++)
    	{
    		a=min(v[i]-1,n-v[i]);
    		if((s1.query(v[i]+a)-s1.query(v[i])+P)*bs[n-v[i]+1]%P!=(s2.query(n-v[i]+1+a)-s2.query(n-v[i]+1)+P)*bs[v[i]]%P)
    		{
    			printf("Y
    ");
    			return ;
    		}
    		s1.updata(v[i],bs[v[i]]),s2.updata(n-v[i]+1,bs[n-v[i]+1]);
    	}
    	printf("N
    ");
    }
    int main()
    {
    	int T=rd();
    	while(T--)	work();
    	return 0;
    }//2 3 1 3 2 3 3 2 1 

     

     
  • 相关阅读:
    Codeforces Round #452 F. Letters Removing
    bzoj 1492: [NOI2007]货币兑换Cash
    bzoj 4016: [FJOI2014]最短路径树问题
    bzoj 2109: [Noi2010]Plane 航空管制
    bzoj 1058: [ZJOI2007]报表统计
    bzoj 1016: [JSOI2008]最小生成树计数
    bzoj 1013: [JSOI2008]球形空间产生器sphere
    bzoj 1758: [Wc2010]重建计划
    bzoj 2337: [HNOI2011]XOR和路径
    一本通1668取石子
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7670397.html
Copyright © 2011-2022 走看看