您的位置:首页 > 其它

hdu 5183 Negative and Positive (NP) (hash大法)

2015-03-09 11:36 316 查看
题意:

给出n个数,这个数一段区间和这样定义 sum[i,j]= ai - ai+1 +......+(-1)^(j-i)aj.给出一个数k,问是否存在一个sum[i,j]==k

题解:

我们手下得出前缀和,然后从后往前推,判断sum[i-1]-k或sum[i-1]+k是否在hash中,然后将sum[i]存入hash。因为题目求的是 sum[j]-sum[i]==k,那么我们将式子变形 sum[i]+k == sum[j] 这样只要判断前者是否在hash中出现就计算了出了i到之后所有j的情况。这题非常坑,读入超时,要手写读入。

#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<hash_map>
#include<set>
using namespace std;
#define B(x) (1<<(x))
typedef __int64 ll;
const int oo=0x3f3f3f3f;
const ll OO=1LL<<61;
const int MOD=10007;
const int maxn=1000005;
ll sum[maxn];
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;
    }
}mat;

template <class T>
inline bool read(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;
}

int main(){

    int n,k,T,sig,f;
    scanf("%d",&T);
    for(int cas=1;cas<=T;cas++){

        mat.init();
        sig=1;f=0;
        read(n);
        read(k);
        sum[0]=0;
        for(int i=1;i<=n;i++){

            read(sum[i]);
            sum[i]=sum[i-1]+sig*sum[i];
            sig*=-1;
        }
        mat.insert(sum
);
        for(int i=n;i>=1&&f==0;i--){

            if(i&1){
                if(mat.check(sum[i-1]+k))f=1;
            }else{
                if(mat.check(sum[i-1]-k))f=1;
            }
            mat.insert(sum[i-1]);
        }
        if(f)printf("Case #%d: Yes.\n",cas);
        else printf("Case #%d: No.\n",cas);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: