题意:给出一个数列{a1, a2, ..., an},问是否存在一段序列ai - ai-1 + ai-2 + ... + aj等于k。
解法:只要求前缀和根据奇偶情况不同+k或-k的值是否存在就可以了……果断用map打了个表……然后T了
然后学了新姿势……哈希大法好啊。
代码:
#include<stdio.h> #include<string.h> using namespace std; typedef long long LL; const int mod = 836131; int info[mod], nxt[1000005]; LL num[1000005]; LL sum[1000005]; int top; inline void inst(LL x) { int y = x % mod; if(y < 0) y += mod; for(int i = info[y]; i; i = nxt[i]) if(num[i] == x) return ; nxt[++top] = info[y]; info[y] = top; num[top] = x; return ; } inline bool query(LL x) { int y = x % mod; if(y < 0) y += mod; for(int i = info[y]; i; i = nxt[i]) if(num[i] == x) return true; return false; } int main() { int T, cse = 1; scanf("%d", &T); while(T--) { memset(info, 0, sizeof(info)); top = 0; int n; LL k; scanf("%d%lld", &n, &k); bool ans = false; sum[0] = 0; for(int i = 1; i <= n; i++) { LL a; scanf("%lld", &a); if(i & 1) sum[i] = sum[i - 1] + a; else sum[i] = sum[i - 1] - a; } for(int i = n; i >= 0; i--) { inst(sum[i]); if(i & 1) { if(query(sum[i] - k)) { ans = true; break; } } else if(query(sum[i] + k)) { ans = true; break; } } printf("Case #%d: ", cse++); if(ans) printf("Yes.\n"); else printf("No.\n"); } }
HDU 5183 Negative and Positive (NP)
原文:http://www.cnblogs.com/Apro/p/4357209.html