zoukankan      html  css  js  c++  java
  • hdu5183 hash大法

    维护前缀和sum[i]=a[0]-a[1]+a[2]-a[3]+…+(-1)^i*a[i]
    枚举结尾i,然后在hash表中查询是否存在sum[i]-K的值。
    如果当前i为奇数,则将sum[i]插入到hash表中。
    上面考虑的是从i为偶数为开头的情况。
    然后再考虑以奇数开头的情况,按照上述方法再做一次即可。
    不同的是这次要维护的前缀和是sum[i]=-(a[0]-a[1]+a[2]-a[3]+…+(-1)^i*a[i])
    I为偶数的时候将sum[i]插入到hash表。
    总复杂度o(n)

    注意一个tips:scanf读long long的时候别忘了%I64d,否则会出错

    ------注意几个黑科技orz-------

    1.这题丧心病狂到了卡常数的程度= =,所以hash的时候用map肯定是不行的。。。。

    借助了kuangbin原创的hash模板orz

    const int HASH = 1000007;
    struct HASHMAP
    {
        int head[HASH],next[MAXN],size;
        long long state[MAXN];
        void init()
        {
            size = 0;
            memset(head,-1,sizeof(head));
        }
        bool check(long long val){
            int h = (val%HASH+HASH)%HASH;
            for(int i = head[h];i != -1;i = next[i])
                if(val == state[i])
                    return true;
            return false;
        }
        int insert(long long val)
        {
            int h = (val%HASH+HASH)%HASH;
            for(int i = head[h]; i != -1;i = next[i])
                if(val == state[i])
                {
                    return 1;
                }
            state[size] = val;
            next[size] = head[h];
            head[h] = size++;
            return 0;
        }
    } H1,H2;

    init:初始化  insert:插入  check:查找是否存在

    2.Huge Data,还需要读入优化:

    基本思想就是把输入数据以一个一个字符的形式读入

    template <class T>
    inline bool scan_d(T &ret) {
       char c; int sgn;
       if(c=getchar(),c==EOF) return 0; //EOF
       while(c!='-'&&(c<'0'||c>'9')) c=getchar();
       sgn=(c=='-')?-1:1;
       ret=(c=='-')?0:(c-'0');
       while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
       ret*=sgn;
       return 1;
    }

    使用方法:scan_d(a[i]);

      1 #include <cstdio>
      2 #include <cstring>
      3 using namespace std;
      4 #define MAXN 1000010
      5 #define LL   long long
      6 int a[MAXN];
      7 LL S1,S2;
      8 LL k;
      9 int n,TC;
     10 
     11 const int HASH = 1000007;
     12 struct HASHMAP
     13 {
     14     int head[HASH],next[MAXN],size;
     15     long long state[MAXN];
     16     void init()
     17     {
     18         size = 0;
     19         memset(head,-1,sizeof(head));
     20     }
     21     bool check(long long val){
     22         int h = (val%HASH+HASH)%HASH;
     23         for(int i = head[h];i != -1;i = next[i])
     24             if(val == state[i])
     25                 return true;
     26         return false;
     27     }
     28     int insert(long long val)
     29     {
     30         int h = (val%HASH+HASH)%HASH;
     31         for(int i = head[h]; i != -1;i = next[i])
     32             if(val == state[i])
     33             {
     34                 return 1;
     35             }
     36         state[size] = val;
     37         next[size] = head[h];
     38         head[h] = size++;
     39         return 0;
     40     }
     41 } H1,H2;
     42 
     43 
     44 template <class T>
     45 inline bool scan_d(T &ret) {
     46    char c; int sgn;
     47    if(c=getchar(),c==EOF) return 0; //EOF
     48    while(c!='-'&&(c<'0'||c>'9')) c=getchar();
     49    sgn=(c=='-')?-1:1;
     50    ret=(c=='-')?0:(c-'0');
     51    while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
     52    ret*=sgn;
     53    return 1;
     54 }
     55 
     56 
     57 int main()
     58 {
     59     //freopen("in.txt","r",stdin);
     60     scanf("%d",&TC);
     61     for (int TT=1;TT<=TC;TT++)
     62     {
     63         scanf("%d%I64d",&n,&k);
     64         for (int i=0;i<n;i++)
     65             scan_d(a[i]);
     66             //scanf("%d",&a[i]);
     67 
     68         bool ans=false;
     69         H1.init();
     70         H2.init();
     71         H1.insert(0);
     72         //H2.insert(0);
     73         S1=a[0];    S2=-a[0];
     74         if (H1.check(S1-k))   ans=true;
     75         if (H2.check(S2-k))   ans=true;
     76         H2.insert(S2);
     77 
     78         for (int i=1;i<n;i++)
     79         {
     80             if (i%2==0)
     81             {
     82                 S1=S1+a[i];
     83                 S2=S2-a[i];
     84                 H2.insert(S2);
     85             }
     86             else
     87             {
     88                 S2=S2+a[i];
     89                 S1=S1-a[i];
     90                 H1.insert(S1);
     91             }
     92             if (H1.check(S1-k))
     93                 ans=true;
     94             if (H2.check(S2-k))
     95                 ans=true;
     96             if (ans)    break;
     97         }
     98 
     99         printf("Case #%d: ",TT);
    100         if (ans)    printf("Yes.
    ");   else printf("No.
    ");
    101     }
    102     return 0;
    103 }
    View Code

    HASH大法有时候真的蛮重要的orz

  • 相关阅读:
    k8s之Controller Manager(七)
    k8s 之apiserver部署(六)
    k8s之etcd集群安装(五)
    k8s 之harbor仓库安装(四)
    k8s 之docker环境部署 (三)
    如何在PPT中同时插入多张图片且每张占一页
    ICMPV6
    整理桌面 | Windows自带工具
    教你在Linux中如何配置网络地址
    解决在gns3中wireshark抓包无法显示和实时刷新问题
  • 原文地址:https://www.cnblogs.com/pdev/p/4322063.html
Copyright © 2011-2022 走看看