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

  • 相关阅读:
    hdu 3790 最短路径问题
    hdu 2112 HDU Today
    最短路问题 以hdu1874为例
    hdu 1690 Bus System Floyd
    hdu 2066 一个人的旅行
    hdu 2680 Choose the best route
    hdu 1596 find the safest road
    hdu 1869 六度分离
    hdu 3339 In Action
    序列化和反序列化
  • 原文地址:https://www.cnblogs.com/pdev/p/4322063.html
Copyright © 2011-2022 走看看