zoukankan      html  css  js  c++  java
  • BZOJ2124 等差子序列(树状数组+哈希)

      容易想到一种暴力的做法:枚举中间的位置,设该位置权值为x,如果其两边存在权值关于x对称即合法。

      问题是如何快速寻找这个东西是否存在。考虑仅将该位置左边出现的权值标1。那么若在值域上若关于x对称的两权值标号不同,说明他们的位置分别在两侧,也就说明存在等差子序列。那么只需要判断整体是否相同,哈希即可。

      哈希值需要动态维护,容易想到树状数组/线段树。从左到右依次处理并维护两个树状数组记录正反哈希值。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 10010
    #define ul unsigned long long
    int T,n,a[N];
    ul tree[N],tree2[N],p[N];
    void add(int k){ul x=p[k-1];while (k<=n) tree[k]+=x,k+=k&-k;}
    void add2(int k){ul x=p[n-k];while (k) tree2[k]+=x,k-=k&-k;}
    ul query(int k){ul s=0;while (k) s+=tree[k],k-=k&-k;return s;}
    ul query2(int k){ul s=0;while (k<=n) s+=tree2[k],k+=k&-k;return s;}
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj2124.in","r",stdin);
        freopen("bzoj2124.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        T=read();
        while (T--)
        {
            n=read();
            for (int i=1;i<=n;i++) a[i]=read();
            p[0]=1;for (int i=1;i<=n;i++) p[i]=p[i-1]*107;
            memset(tree,0,sizeof(tree));
            memset(tree2,0,sizeof(tree2));
            bool flag=0;
            for (int i=1;i<=n;i++)
            {
                if (a[i]-1<n-a[i])
                {
                    if (query(a[i]-1)*p[n-(a[i]<<1)+1]!=query2(a[i]+1)-query2(a[i]<<1)) {flag=1;break;} 
                }
                else
                {
                    if (query2(a[i]+1)*p[a[i]-(n-a[i])-1]!=query(a[i]-1)-query(a[i]-(n-a[i])-1)) {flag=1;break;}
                }
                add(a[i]);add2(a[i]);
            }
            if (flag) printf("Y
    ");else printf("N
    ");
        }
        return 0;
    }
  • 相关阅读:
    关于document.body.scrollLeft总是0的原因
    转载:如何配置 SQL Server 2005 以允许远程连接
    【转载】SQL Server中Rollup关键字使用技巧
    JavaScript代码优化
    JavaScript中定义类或对象
    【转载】SQLServer2005 Pivot 转置使用动态列
    迅雷刷分
    ROW_NUMBER() OVER函数的基本用法用法
    FireFox下表单无法刷新重置的解决
    SQL 远程查询
  • 原文地址:https://www.cnblogs.com/Gloid/p/9550420.html
Copyright © 2011-2022 走看看