XX Open Cup Grand Prix of SPb 做题记录

B.

将$8\times8$的棋盘坐标 01 分解。定义棋盘的值为

$$ \oplus_{i, j}[a_{ij}]\cdot(8i+j) $$

其中$\oplus$为异或和,$a_{ij}$为$i$行$j$列是否为$1$。这样棋盘的每一格都唯一对应$[0, 63]$的一个数,且棋盘的值也是这样的一个数。

假设当前棋盘值为$v$,我们期望得到一个$[0,63]$的一个数$x$,我们只需将$x\mathrm{xor} v$对应的格子取反即可。

注意原题目要求的数域是$[1,64]$。

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 const int N = 8;
 6 
 7 bool a[N][N];
 8 
 9 int calc() {
10     int ret = 0;
11     for (int i = 0; i < N; ++i) 
12         for (int j = 0; j < N; ++j) 
13             if (a[i][j]) 
14                 ret ^= i * 8 + j;
15     return ret;
16 }
17 
18 int main() {
19     ios::sync_with_stdio(false);
20     string name;
21     cin >> name;
22     if (name == "Mia") {
23         int t;
24         cin >> t;
25         while (t--) {
26             int num;
27             for (int i = 0; i < N; ++i)
28                 for (int j = 0; j < N; ++j)
29                     cin >> a[i][j];
30             cin >> num;
31             num--;
32             int cur = calc();
33             int tmp = num ^ cur;
34             a[tmp / 8][tmp % 8] ^= 1;
35             assert(calc() == num);
36             for (int i = 0; i < N; ++i)
37                  for (int j = 0; j < N; ++j)
38                     cout << a[i][j] << " \n"[j == N - 1];
39             cout << "---\n";
40         }
41     } else if (name == "Danila") {
42         int t;
43         cin >> t;
44         while (t--) {
45             int num;
46             for (int i = 0; i < N; ++i)
47                 for (int j = 0; j < N; ++j)
48                     cin >> a[i][j];
49             string tmp;
50             cin >> tmp;
51             cout << calc() + 1 << endl;
52         }
53     }
54 }
View Code

 E.

签到题。注意对$0$特殊处理。

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 string tostr(unsigned x) {
 6     string ret = "";
 7     while (x % 2 == 0) {
 8         x >>= 1;
 9     }
10     while (x) {
11         if (x & 1) {
12             ret += "1";
13         } else {
14             ret += "0";
15         }
16         x >>= 1;
17     }
18     return ret;
19 }
20 
21 int main() {
22     // freopen("in", "r", stdin);
23     // freopen("out", "w", stdout);
24     ios::sync_with_stdio(false);
25     int T;
26     cin >> T;
27     while (T--) {
28         unsigned x, y;
29         cin >> x >> y;
30         if (y == 0) {
31             cout << "Yes\n";
32         } else if (x == 0) {
33             cout << "No\n";
34         } else {        
35             string a = tostr(x), b = tostr(y);
36             if (a.find(b) == string::npos) {
37                 cout << "No\n";
38             } else {
39                 cout << "Yes\n";
40             }
41         }
42     }
43 }
View Code

F.

对所有边以边的贡献从大到小排序,依次贪心取边即可。这需要维护一个节点到根的最小值以及区间减法。(学傻了)所以用重链剖分维护。

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 typedef pair<int, int> pii;
  6 
  7 const int MAXN = 100000 + 10;
  8 
  9 struct Edge {
 10     int v, n;
 11     int64_t w;
 12     Edge(int v=0, int n=0, int64_t w=0) : v(v), n(n), w(w) {}
 13 } e[MAXN << 1];
 14 int G[MAXN], edgeCnt;
 15 
 16 void add_edge(int u, int v, int w) { // from up to down
 17     e[++edgeCnt] = Edge(v, G[u], w);
 18     G[u] = edgeCnt;
 19 }
 20 
 21 int sz[MAXN], ch[MAXN], par[MAXN], dep[MAXN], top[MAXN];
 22 int id[MAXN], alloc;
 23 int val[MAXN], cap[MAXN];
 24 
 25 void dfs_1(int u) {
 26     sz[u] = 1, ch[u] = 0;
 27     for (int i = G[u]; i; i = e[i].n) {
 28         par[e[i].v] = u;
 29         dep[e[i].v] = dep[u] + 1;
 30         dfs_1(e[i].v);
 31         sz[u] += sz[e[i].v];
 32         if (sz[e[i].v] > sz[ch[u]])
 33             ch[u] = e[i].v;
 34     }
 35 }
 36 
 37 void dfs_2(int u, int anc) {
 38     id[u] = ++alloc;
 39     top[u] = anc;
 40     if (ch[u])
 41         dfs_2(ch[u], anc);
 42     for (int i = G[u]; i; i = e[i].n) if (e[i].v != ch[u]) {
 43         dfs_2(e[i].v, e[i].v);
 44     }
 45 }
 46 
 47 int mn[MAXN << 2], tag[MAXN << 2];
 48 int a[MAXN];
 49 int n, t;
 50 
 51 inline void push_up(int o) { mn[o] = min(mn[o << 1], mn[o << 1 | 1]); }
 52 inline void change(int o, int v) {mn[o] += v, tag[o] += v; }
 53 void push_down(int o) {
 54     if (tag[o]) {
 55         change(o << 1, tag[o]);
 56         change(o << 1 | 1, tag[o]);
 57         tag[o] = 0;
 58     }
 59 }
 60 
 61 void add(int ql, int qr, int x, int l=2, int r=n, int o=1) {
 62     if (ql == l && qr == r) {
 63         change(o, x);
 64         return;
 65     }
 66     push_down(o);
 67     int mid = (l + r) >> 1;
 68     if (qr <= mid)
 69         add(ql, qr, x, l, mid, o << 1);
 70     else if (mid < ql)
 71         add(ql, qr, x, mid + 1, r, o << 1 | 1);
 72     else {
 73         add(ql, mid, x, l, mid, o << 1);
 74         add(mid + 1, qr, x, mid + 1, r, o << 1 | 1);
 75     }
 76     push_up(o);
 77 }
 78 
 79 int query(int ql, int qr, int l=2, int r=n, int o=1) {
 80     if (ql == l && qr == r)
 81         return mn[o];
 82     push_down(o);
 83     int mid = (l + r) >> 1;
 84     if (qr <= mid)
 85         return query(ql, qr, l, mid, o << 1);
 86     else if (mid < ql)
 87         return query(ql, qr, mid + 1, r, o << 1 | 1);
 88     else
 89         return min(query(ql, mid, l, mid, o << 1), query(mid + 1, qr, mid + 1, r, o << 1 | 1));
 90 }
 91 
 92 void build(int l, int r, int o=1) {
 93     if (l == r) {
 94         mn[o] = a[l];
 95         return;
 96     }
 97     int mid = (l + r) >> 1;
 98     build(l, mid, o << 1);
 99     build(mid + 1, r, o << 1 | 1);
100     push_up(o);
101 }
102 
103 int qmin(int u) {
104     int ret = INT_MAX;
105     while (top[u] != 1) {
106         ret = min(ret, query(id[top[u]], id[u]));
107         u = par[top[u]];
108     }
109     if (u == 1)
110         return ret;
111     return min(ret, query(id[ch[1]], id[u]));
112 }
113 
114 void qadd(int u, int x) {
115     while (top[u] != 1) {
116         add(id[top[u]], id[u], x);
117         u = par[top[u]];
118     }
119     if (u != 1)
120         add(id[ch[1]], id[u], x);
121 }
122 
123 int main() {
124     ios::sync_with_stdio(false);
125     cin >> n >> t;
126     vector<pii> qwq;
127     for (int v = 2; v <= n + 1; ++v) {
128         int u, w;
129         cin >> val[v] >> u >> cap[v];
130         u++;
131         add_edge(u, v, cap[v]);
132         qwq.push_back(pii(val[v], v));
133     }
134     n++;
135     dfs_1(1);
136     dfs_2(1, 1);
137     for (int i = 1; i <= n; ++i)
138         a[id[i]] = cap[i];
139     build(2, n);
140     sort(qwq.begin(), qwq.end(), greater<pii>());
141     int64_t ans = 0;
142     for (auto& x : qwq) {
143         int mval = qmin(x.second);
144         if (mval < t) {
145             qadd(x.second, -mval);
146             ans += 1ll * mval * x.first;
147             t -= mval;
148         } else {
149             ans += 1ll * t * x.first;
150             break;
151         }
152     }
153     cout << ans << endl;
154 }
View Code

H.

码农题。令每次吃都吃有空缺的那一头,每次补都补满,这样可以保证吃到的永远最新鲜。设计状态然后输出状态转移即可。

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 bool a[16];
  6 
  7 int encode() {
  8     int ret = 0;
  9     for (int i = 0; i < 16; ++i)
 10         ret = ret * 2 + a[i];
 11     return ret; 
 12 }
 13 
 14 void decode(int code) {
 15     for (int i = 15; i >= 0; --i) {
 16         a[i] = code % 2;
 17         code >>= 1;
 18     }
 19 }
 20 
 21 bool vis[(1 << 16) + 5];
 22 
 23 void print(int st1, int st2, string str) {
 24     string l1, l2;
 25     decode(st1);
 26     for (int i = 0; i < 4; ++i)
 27         l1 += (a[i] == 1 ? "*" : ".");
 28     l1 += '|';
 29     for (int i = 4; i < 8; ++i)
 30         l1 += (a[i] == 1 ? "*" : ".");
 31     l1 += " " + str + " ";
 32 
 33     for (int i = 8; i < 12; ++i)
 34         l2 += (a[i] == 1 ? "*" : ".");
 35     l2 += '|';
 36     for (int i = 12; i < 16; ++i)
 37         l2 += (a[i] == 1 ? "*" : ".");
 38     l2 += "     ";
 39 
 40     decode(st2);
 41     for (int i = 0; i < 4; ++i)
 42         l1 += (a[i] == 1 ? "*" : ".");
 43     l1 += '|';
 44     for (int i = 4; i < 8; ++i)
 45         l1 += (a[i] == 1 ? "*" : ".");
 46 
 47     for (int i = 8; i < 12; ++i)
 48         l2 += (a[i] == 1 ? "*" : ".");
 49     l2 += '|';
 50     for (int i = 12; i < 16; ++i)
 51         l2 += (a[i] == 1 ? "*" : ".");
 52 
 53     cout << l1 << endl << l2 << "\n---\n";
 54 }
 55 
 56 int count() {
 57     int ret = 0;
 58     for (int i = 0; i < 16; ++i)
 59         ret += a[i];
 60     return ret;
 61 }
 62 
 63 inline int lfirst() {
 64     for (int i = 0; i < 16; ++i)
 65         if (a[i])
 66             return i;
 67     return -1;
 68 }
 69 
 70 inline int rfirst() {
 71     for (int i = 15; i >= 0; --i)
 72         if (a[i])
 73             return i;
 74     return -1;
 75 }
 76 
 77 void dfs(int st) {
 78     if (vis[st])
 79         return;
 80     vis[st] = true;
 81     decode(st);
 82     int cnt = count();
 83     if (cnt == 0) {
 84         for (int i = 0; i < 10; ++i)
 85             a[i] = 1;
 86         print(st, encode(), "buy");
 87         dfs(encode());
 88         for (int i = 0; i < 10; ++i)
 89             a[i] = 0;
 90     } else if (cnt > 6) {
 91         int x;
 92         if (a[0] == 1) {
 93             x = rfirst();
 94         } else if (a[15] == 1) {
 95             x = lfirst();
 96         }
 97         a[x] = 0;
 98         print(st, encode(), "eat");
 99         dfs(encode());
100         a[x] = 1;
101     } else if (cnt == 6) {
102         int x;
103         if (a[0] == 1) {
104             x = 0;
105         } else if (a[15] == 1) {
106             x = 15;
107         }
108         a[x] = 0;
109         print(st, encode(), "eat");
110         dfs(encode());
111         a[x] = 1;
112     } else if (cnt <= 5) {
113         int x = 0;
114         if (lfirst() == 10) {
115             x = rfirst();
116         } else if (rfirst() == 5) {
117             x = lfirst();
118         }
119         a[x] = 0;
120         print(st, encode(), "eat");
121         dfs(encode());
122         a[x] = 1;
123 
124         if (lfirst() == 10) {
125             for (int i = 0; i < 10; ++i) {
126                 a[i] = 1;
127             }
128             print(st, encode(), "buy");
129             dfs(encode());
130             for (int i = 0; i < 10; ++i) {
131                 a[i] = 0;
132             }
133         } else if (rfirst() == 5) {
134             for (int i = 15; i > 5; --i) {
135                 a[i] = 1;
136             }
137             print(st, encode(), "buy");
138             dfs(encode());
139             for (int i = 15; i > 5; --i) {
140                 a[i] = 0;
141             }
142         }
143     }
144 }
145 
146 int main() {
147     ios::sync_with_stdio(false);
148     dfs(0);
149 }
View Code

猜你喜欢

转载自www.cnblogs.com/uuzhateteee/p/12632935.html