根据奇偶开两个hash表来记录后缀和。注意set会被卡,要手写hash表。

  具体见代码:

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <string.h>
 4 using namespace std;
 5 const int N = 1000000 + 10;
 6 const int HASH = 1000000 + 7;
 7 typedef long long ll;
 8 struct hashmap
 9 {
10     int head[HASH], nxt[N], size;
11     ll state[N];
12     void init()
13     {
14         size = 0;
15         memset(head,-1,sizeof(head));
16     }
17     bool check(ll val)
18     {
19         int temp = (val%HASH + HASH) % HASH;
20         for(int i=head[temp];i!=-1;i=nxt[i])
21         {
22             if(val == state[i]) return true;
23         }
24         return false;
25     }
26     void add(ll val)
27     {
28         int temp = (val%HASH + HASH) % HASH;
29         if(check(val)) return;
30         size ++;
31         state[size] = val;
32         nxt[size] = head[temp];
33         head[temp] = size;
34     }
35 }h1,h2;
36 
37 ll a[N];
38 
39 int main()
40 {
41     int T, kase = 1;
42     scanf("%d",&T);
43     while(T--)
44     {
45         h1.init();h2.init();
46         h1.add(0);h2.add(0);
47         int n,k;
48         scanf("%d%d",&n,&k);
49         for(int i=1;i<=n;i++)
50         {
51             scanf("%I64d",a+i);
52         }
53         ll sum = 0;
54         bool flag = false;
55         for(int i=n;i>=1;i--)
56         {
57             if(i%2 == 0) sum += a[i];
58             else sum -= a[i];
59             if(i%2 == 0)
60             {
61                 if(h1.check(sum-k)) flag = true;
62             }
63             else if(h2.check(-sum-k)) flag = true;
64             if(flag) break;
65             h1.add(sum);
66             h2.add(-sum);
67         }
68         printf("Case #%d: %s.\n",kase++, flag?"Yes":"No");
69     }
70     return 0;
71 }