Pentium.Labs

System全家桶:https://zhuanlan.zhihu.com/c_1238468913098731520

导航

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.\n");   else printf("No.\n");
101     }
102     return 0;
103 }
View Code

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

posted on 2015-03-08 18:27  Pentium.Labs  阅读(206)  评论(0编辑  收藏  举报



Pentium.Lab Since 1998