HDU 5183 Negative and Positive (NP) 前缀和+哈希
题目链接:
hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5183
bc(中文):http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=570&pid=1002
题解:
前缀和+哈希
维护两张哈希表hash1,hash2,一张维护前缀和sum=a[0]-a[1]+a[2]-a[3]+...+(-1)^i*a[i],另一张维护-sum=-a[0]+a[1]-a[2]+a[3]-...+(-1)^(i+1)*a[i];当i为奇数的时候,插入到第一张哈希表hash1,当i为偶数的时候插入到第二张表hash2,每次查询在hash1中是否存在sum-k,或在hash2中是否存在-sum-k,如果有一个条件成立,则说明有解。否则继续做下去,直到最后还没有答案则无解。
代码:
hash表大小设为100007,输入为int,用vector做hash,g++,1185MS高飘
1 #include<map> 2 #include<cstdio> 3 #include<vector> 4 #include<cstring> 5 #include<iostream> 6 #include<algorithm> 7 using namespace std; 8 9 typedef long long LL; 10 11 const int mod = 100007; 12 13 int n,k; 14 15 vector<LL> v[2][mod]; 16 17 int Hash(LL x) { 18 return (x%mod + mod) % mod; 19 } 20 21 bool que(LL x,int type) { 22 int key = Hash(x); 23 for (int i = 0; i < v[type][key].size(); i++) { 24 if (v[type][key][i] == x) return true; 25 } 26 return false; 27 } 28 29 void add(LL x,int type) { 30 int key = Hash(x); 31 if (!que(x,type)) { 32 v[type][key].push_back(x); 33 } 34 } 35 36 void init() { 37 for (int i = 0; i < mod; i++) { 38 v[0][i].clear(); 39 v[1][i].clear(); 40 } 41 } 42 43 int main() { 44 int tc, kase=0; 45 scanf("%d", &tc); 46 while (tc--) { 47 scanf("%d%d", &n, &k); 48 init(); 49 LL sum = 0; 50 bool ans = 0; 51 for (int i = 0; i < n; i++) { 52 int x; 53 scanf("%d", &x); 54 if (i & 1) sum -= x; 55 else sum += x; 56 if (que(sum - k,0) || que(-sum - k,1)) { 57 ans = true; 58 } 59 if (i & 1) add(sum, 0); 60 else add(-sum, 1); 61 } 62 if (sum == k) ans = true; 63 printf("Case #%d: ",++kase); 64 if (ans) printf("Yes.\n"); 65 else printf("No.\n"); 66 } 67 return 0; 68 }
hash表大小1000007,输入int,邻接表做hash,g++, 811ms
1 #include<map> 2 #include<cstdio> 3 #include<vector> 4 #include<cstring> 5 #include<iostream> 6 #include<algorithm> 7 using namespace std; 8 9 typedef long long LL; 10 11 const int mod = 1000007; 12 const int maxn=1000000+10; 13 14 struct Edge{ 15 LL x; int ne; 16 Edge(LL x,int ne):x(x),ne(ne){} 17 Edge(){} 18 }egs[maxn*2]; 19 20 int n,k; 21 22 int v[2][mod],tot; 23 24 int Hash(LL x) { 25 return (x%mod + mod) % mod; 26 } 27 28 bool que(LL x,int type) { 29 int key = Hash(x); 30 int p=v[type][key]; 31 while(p!=-1){ 32 Edge& e=egs[p]; 33 if(e.x==x) return true; 34 p=e.ne; 35 } 36 return false; 37 } 38 39 void add(LL x,int type) { 40 int key = Hash(x); 41 if (!que(x,type)) { 42 egs[tot]=Edge(x,v[type][key]); 43 v[type][key]=tot++; 44 } 45 } 46 47 void init() { 48 memset(v,-1,sizeof(v)); 49 tot=0; 50 } 51 52 int main() { 53 int tc, kase=0; 54 scanf("%d", &tc); 55 while (tc--) { 56 scanf("%d%d", &n, &k); 57 init(); 58 LL sum = 0; 59 bool ans = 0; 60 for (int i = 0; i < n; i++) { 61 int x; 62 scanf("%d", &x); 63 if (i & 1) sum -= x; 64 else sum += x; 65 if (que(sum - k,0) || que(-sum - k,1)) { 66 ans = true; 67 } 68 if (i & 1) add(sum, 0); 69 else add(-sum, 1); 70 } 71 if (sum == k) ans = true; 72 printf("Case #%d: ",++kase); 73 if (ans) printf("Yes.\n"); 74 else printf("No.\n"); 75 } 76 return 0; 77 }