## 【十二省联考 2019】异或粽子 解题报告

 1 // P1631 序列合并
2
3 #include <ctime>
4 #include <cmath>
5 #include <cstdio>
6 #include <cstring>
7 #include <cstdlib>
8 #include <iostream>
9 #include <algorithm>
10 #include <vector>
11 #include <queue>
12 #define inf 100010
13 #define INF 0x7fffffff
14 #define ll long long
15
16 namespace chiaro{
17
18 template <class I>
20     num = 0; char c = getchar(), up = c;
21     while(c < '0' || c > '9') up = c, c = getchar();
22     while(c >= '0' && c <= '9') num = (num << 1) + (num << 3) + (c ^ '0'), c = getchar();
23     up == '-' ? num = -num : 0; return;
24 }
25 template <class I>
27 template <class I>
29
30 struct Node {
31     int i, j;
32     int dis;
33     inline bool operator < (const Node& other) const {
34         return dis > other.dis;
35     }
36     Node() {i = j = dis = 0;}
37     Node(int a, int b, int c) {i = a, j = b, dis = c;}
38 };
39
40 int n;
41 int a[inf], b[inf];
42 std::priority_queue <Node, std::vector <Node> > P;
43
44 inline int main(){
46     for(int i = 1; i <= n; i++) read(a[i]);
47     for(int i = 1; i <= n; i++) read(b[i]);
48     P.push((Node){1, 1, a[1] + b[1]});
49     for(int i = 1; i <= n; i++) {
50         Node x = P.top(); P.pop();
51         printf("%d ", x.dis);
52         P.push((Node){x.i, x.j + 1, a[x.i] + b[x.j + 1]});
53         if(x.j == 1) P.push((Node){x.i + 1, x.j, a[x.i + 1] + b[x.j]});
54     }
55     return 0;
56 }
57
58 }
59
60 signed main(){ return chiaro::main();}

 1 // P2048 [NOI2010]超级钢琴
2
3 #include <ctime>
4 #include <cmath>
5 #include <cstdio>
6 #include <cstring>
7 #include <cstdlib>
8 #include <iostream>
9 #include <algorithm>
10 #include <vector>
11 #include <queue>
12 #define inf 500010
13 #define INF 0x7fffffff
14 #define ll long long
15
16 namespace chiaro{
17
18 template <class I>
20     num = 0; char c = getchar(), up = c;
21     while(c < '0' || c > '9') up = c, c = getchar();
22     while(c >= '0' && c <= '9') num = (num << 1) + (num << 3) + (c ^ '0'), c = getchar();
23     up == '-' ? num = -num : 0; return;
24 }
25 template <class I>
27 template <class I>
29
30 struct Node {
31     int x;
32     int l, r;
33     int p;
34     Node() {x = l = r = p = 0;}
35     Node(int a, int b, int c, int d) {x = a, l = b, r = c, p = d;}
36 };
37
38 int n, k;
39 int L, R;
40 int a[inf];
41 ll sum[inf];
42
43 ll table[24][inf];
44 int log[inf];
45
46 std::priority_queue <Node, std::vector <Node> > P;
47
48 inline bool operator < (const Node& now, const Node& other) {
49     return (sum[now.p] - sum[now.x - 1]) < (sum[other.p] - sum[other.x - 1]);
50 }
51
52 #define max(a, b) (sum[(a)] > sum[(b)] ? (a) : (b))
53
54 inline void build(int n) {
55     for(int i = 2; i <= n; i++) log[i] = log[i >> 1] + 1;
56     for(int i = 1; i <= n; i++) table[0][i] = i;
57     for(int j = 1; (1 << j) <= n; j++) {
58         for(int i = 1; i + (1 << j) - 1 <= n; i++) {
59             int x = table[j - 1][i];
60             int y = table[j - 1][i + (1 << (j - 1))];
61             table[j][i] = max(x, y);
62         }
63     }
64 }
65
66 inline int query(int l, int r) {
67     int k = log[r - l + 1];
68     int x = table[k][l];
69     int y = table[k][r - (1 << k) + 1];
70     return max(x, y);
71 }
72
73 inline int main(){
75     for(int i = 1; i <= n; i++) read(a[i]);
76     for(int i = 1; i <= n; i++) sum[i] = sum[i - 1] + a[i];
77     build(n);
78     for(int i = 1; i <= n; i++) {
79         if(i + L - 1 > n) break;
80         int l = i + L - 1;
81         int r = std::min (n, i + R - 1);
82         P.push((Node){i, l, r, query(l, r)});
83     }
84     ll ans = 0;
85     while(k--) {
86         Node x = P.top(); P.pop();
87         ans += sum[x.p] - sum[x.x - 1];
88         if(x.p != x.l) P.push((Node){x.x, x.l, x.p - 1, query(x.l, x.p - 1)});
89         if(x.p != x.r) P.push((Node){x.x, x.p + 1, x.r, query(x.p + 1, x.r)});
90     }
91     printf("%lld\n", ans);
92     return 0;
93 }
94
95 }
96
97 signed main(){ return chiaro::main();}

zhq：看到亦或和最大就应该想到 Trie

 1 #include <ctime>
2 #include <cmath>
3 #include <cstdio>
4 #include <cstring>
5 #include <cstdlib>
6 #include <iostream>
7 #include <algorithm>
8 #include <vector>
9 #include <queue>
10 #define inf 500010
11 #define INF 0x7fffffff
12 #define ll long long
13 #define int unsigned int
14
15 namespace chiaro{
16
17 template <class I>
19     num = 0; char c = getchar(), up = c;
20     while(c < '0' || c > '9') up = c, c = getchar();
21     while(c >= '0' && c <= '9') num = (num << 1) + (num << 3) + (c ^ '0'), c = getchar();
22     up == '-' ? num = -num : 0; return;
23 }
24 template <class I>
26 template <class I>
28
29 struct Node {
30     int id;
31     int rk;
32     int dis;
33     Node(int a, int b, int c) {id = a, rk = b, dis = c;}
34
35     inline bool operator < (const Node& other) const {
36         return dis < other.dis;
37     }
38 };
39
40 struct Trie {
41     int ch[2];
42     int size;
43 };
44
45 int n, k;
46 ll ans;
47 int a[inf];
48 int sum[inf];
49 Trie t[inf * 32];
50 std::priority_queue <Node, std::vector <Node> > P;
51
52 #define next  (t[now].ch[bit])
53 #define xnext (t[now].ch[bit ^ 1])
54
55 inline void insert(int x) {
56     static int index = 0;
57     int now = 0;
58     for(int i = 31; i < 32; i--) {
59         int bit = (x >> i) & 1;
60         ++t[now].size;
61         if(next == 0) next = ++index;
62         now = next;
63     }
64     ++t[now].size;
65     return;
66 }
67
68 inline int query(int x, int rk) {
69     int ans = 0;
70     int now = 0;
71     for(int i = 31; i < 32; i--) {
72         int bit = (x >> i) & 1;
73         if(xnext == 0) now = next;
74         else if(rk <= t[xnext].size) now = xnext, ans |= (1u << i);
75         else rk -= t[xnext].size, now = next;
76     }
77     return ans;
78 }
79
80 inline int main(){
81     read(n, k); k <<= 1;
82     for(int i = 1; i <= n; i++) read(a[i]);
83     for(int i = 1; i <= n; i++) sum[i] = sum[i - 1] ^ a[i];
84     for(int i = 0; i <= n; i++) insert(sum[i]);
85     for(int i = 0; i <= n; i++) P.push((Node){i, 1, query(sum[i], 1)});
86     for(int i = 1; i <= k; i++) {
87         Node x = P.top(); P.pop();
88         ans += x.dis;
89         if(x.rk >= n) continue;
90         P.push((Node){x.id, x.rk + 1, query(sum[x.id], x.rk + 1)});
91     }
92     printf("%lld\n", ans >> 1);
93     return 0;
94 }
95
96 }
97
98 signed main(){ return chiaro::main();}