题意:问是否存在一段区间其加减交错和为K。
显然,我们可以用set保存前缀和,然后枚举一个端点查找。具体的
若在st1中查找 $t$,为 $sum-t=-k$,在st2中则是 $sum-t=k$。
注意这样作差的话,没有考虑到 $a_1$ 开始的,只要在st2中插入一个0即可。
然而,这题卡set,必须手写hashmap(说实话,之前不太相信会有卡set的题!)
后来发现unordered_set也能过(刚好过)
分别是unordered_set、set、手写hashmap
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1000000 + 10; int n, k; //set<ll>st1, st2; const unsigned long long SMod = 1000007; struct Hashmap { struct Node { long long num; int next; }; Node nodes[2*maxn]; int cnt_node; //节点个数 int head[SMod+10]; //链表的头 void init() { memset(head, - 1, sizeof(head)); cnt_node = 0; } void insert(long long num) { int pos = num % SMod; //在链表头中的位置 nodes[cnt_node].next = head[pos]; nodes[cnt_node].num = num; head[pos] = cnt_node; cnt_node++; } long long find(long long num) //找到的话返回节点编号,没找到返回-1 { int pos = num % SMod; for(int i = head[pos]; i != -1; i = nodes[i].next) { if(nodes[i].num == num) return i; } return -1; } }st1, st2; int main() { int T, kase=0; scanf("%d", &T); while(T--) { scanf("%d%d", &n, &k); ll sum = 0; bool flag = false; st1.init(); st2.init(); st2.insert(0); for(int i = 1;i <= n;i++) { int tmp; scanf("%d", &tmp); if(i&1){ sum += tmp; st1.insert(sum);} else { sum -= tmp; st2.insert(sum);} //printf("sum:%d\n", sum); if(st1.find(sum+k) != -1|| st2.find(sum-k) != -1) flag = true; } printf("Case #%d: ", ++kase); if(flag) printf("Yes.\n"); else printf("No.\n"); } }