The 2018 ACM-ICPC Asia Qingdao Regional Contest, Online Solution
分类:
IT文章
•
2025-01-09 08:38:32
A Live Love
水。
1 #include<bits/stdc++.h>
2
3 using namespace std;
4
5 typedef long long ll;
6 const double eps = 1e-8;
7 const int INF = 0x3f3f3f3f;
8 const ll MOD = (int)1e9 + 7;
9 const int maxn = (int)1e6 + 10;
10
11 int n, m;
12
13 inline void RUN()
14 {
15 int t;
16 scanf("%d", &t);
17 while (t--)
18 {
19 scanf("%d %d", &n, &m);
20 int ans1 = m;
21 int ans2 = (n) / (n - m + 1);
22 printf("%d %d
", ans1, ans2);
23 }
24 }
25
26 int main()
27 {
28 #ifdef LOCAL_JUDGE
29 freopen("Text.txt", "r", stdin);
30 #endif // LOCAL_JUDGE
31
32 RUN();
33
34 #ifdef LOCAL_JUDGE
35 fclose(stdin);
36 #endif // LOCAL_JUDGE
37 return 0;
38 }
View Code
B Red Black Tree
题意:有一个树,上面有红点和黑点,有边权,每个点的花费定义为它到离它最近的红点的距离,每次询问给出一些点,能够将这棵树中的一个黑点变为红点,使得这些点中的最大花费最小
思路:二分答案,符合条件的点不管,将不符合条件的点LCA求出来,变红,然后算距离
1 #include <bits/stdc++.h>
2 using namespace std;
3
4 #define N 100010
5 #define ll long long
6 #define INFLL 0x3f3f3f3f3f3f3f3f
7
8 struct Edge
9 {
10 int to, nx; ll w;
11 inline Edge() {}
12 inline Edge(int to, int nx, ll w) : to(to), nx(nx), w(w) {}
13 }edge[N << 1];
14
15 int t, n, m, q, k;
16 int isred[N], prered[N], head[N], arr[N], pos;
17 int rmq[N << 1], F[N << 1], P[N], deep[N], cnt;
18 ll dist[N];
19
20 inline void Init()
21 {
22 memset(head, -1, sizeof head); pos = 0;
23 memset(isred, 0, sizeof isred); deep[1] = 0;
24 }
25
26 inline void addedge(int u, int v, ll w)
27 {
28 edge[++pos] = Edge(v, head[u], w); head[u] = pos;
29 }
30
31 struct ST
32 {
33 int mm[N << 1];
34 int dp[N << 1][20];
35 inline void init(int n)
36 {
37 mm[0] = -1;
38 for (int i = 1; i <= n; ++i)
39 {
40 mm[i] = ((i & (i - 1)) == 0) ? mm[i - 1] + 1 : mm[i - 1];
41 dp[i][0] = i;
42 }
43 for (int j = 1; j <= mm[n]; ++j)
44 {
45 for (int i = 1; i + (1 << j) - 1 <= n; ++i)
46 {
47 dp[i][j] = rmq[dp[i][j - 1]] < rmq[dp[i + (1 << (j - 1))][j - 1]] ? dp[i][j - 1] : dp[i + (1 << (j - 1))][j - 1];
48 }
49 }
50 }
51 inline int query(int a, int b)
52 {
53 if (a > b) swap(a, b);
54 int k = mm[b - a + 1];
55 return rmq[dp[a][k]] <= rmq[dp[b - (1 << k) + 1][k]] ? dp[a][k] : dp[b - (1 << k) + 1][k];
56 }
57 }st;
58
59 inline void DFS(int u, int pre, int prer)
60 {
61 F[++cnt] = u;
62 rmq[cnt] = deep[u];
63 P[u] = cnt;
64 prered[u] = prer;
65 for (int it = head[u]; ~it; it = edge[it].nx)
66 {
67 int v = edge[it].to;
68 if (v == pre) continue;
69 if (isred[v]) dist[v] = 0;
70 else dist[v] = dist[u] + edge[it].w;
71 deep[v] = deep[u] + 1;
72 DFS(v, u, isred[v] ? v : prer);
73 F[++cnt] = u;
74 rmq[cnt] = deep[u];
75 }
76 }
77
78 inline void Lca_Init(int root, int node_num)
79 {
80 cnt = 0;
81 DFS(root, root, 1);
82 st.init(2 * node_num - 1);
83 }
84
85 inline int query_lca(int u, int v)
86 {
87 return F[st.query(P[u], P[v])];
88 }
89
90 vector <int> v;
91 inline bool check(ll mid)
92 {
93 v.clear();
94 for (int i = 1; i <= k; ++i)
95 {
96 if (dist[arr[i]] > mid)
97 v.emplace_back(arr[i]);
98 }
99 if (v.empty()) return true;
100 int lca = v[0];
101 for (int i = 1, len = v.size(); i < len; ++i)
102 lca = query_lca(lca, v[i]);
103 if (isred[lca]) return false;
104 for (auto it : v)
105 {
106 if (deep[lca] < deep[prered[it]]) return false;
107 else if (dist[it] - dist[lca] > mid) return false;
108 }
109 return true;
110 }
111
112 inline void Run()
113 {
114 for (scanf("%d", &t); t--; )
115 {
116 scanf("%d%d%d", &n, &m, &q); Init();
117 for (int i = 1, u; i <= m; ++i)
118 {
119 scanf("%d", &u);
120 isred[u] = 1;
121 }
122 ll w;
123 for (int i = 1, u, v; i < n; ++i)
124 {
125 scanf("%d%d%lld", &u, &v, &w);
126 addedge(u, v, w); addedge(v, u, w);
127 }
128 Lca_Init(1, n);
129 for (int qq = 1; qq <= q; ++qq)
130 {
131 scanf("%d", &k);
132 for (int i = 1; i <= k; ++i) scanf("%d", arr + i);
133 if (k == 1)
134 {
135 puts("0");
136 continue;
137 }
138 ll l = 0, r = INFLL, ans;
139 while (r - l >= 0)
140 {
141 ll mid = (l + r) >> 1;
142 if (check(mid))
143 {
144 ans = mid;
145 r = mid - 1;
146 }
147 else
148 l = mid + 1;
149 }
150 printf("%lld
", ans);
151 }
152 }
153 }
154
155 int main()
156 {
157 #ifdef LOCAL
158 freopen("Test.in", "r", stdin);
159 #endif
160
161 Run();
162 return 0;
163 }
View Code
愚蠢的倍增求LCA(排序一下)
1 #include<bits/stdc++.h>
2
3 using namespace std;
4
5 typedef long long ll;
6
7 const int INF = 0x3f3f3f3f;
8 const ll INFLL = 0x3f3f3f3f3f3f3f3f;
9 const ll MOD = (int)1e9 + 7;
10 const int maxn = (int)1e5 + 10;
11
12 const int DEG = 20;
13
14 struct Edge {
15 int to, nxt;
16 ll w;
17 inline Edge(){}
18 inline Edge(int to,int nxt,ll w):to(to),nxt(nxt),w(w){}
19 }edge[maxn << 1];
20
21 int head[maxn], tot;
22 int red[maxn];
23
24 inline void addedge(int u, int v, ll w)
25 {
26 edge[tot] = Edge(v, head[u], w); head[u] = tot++;
27 }
28
29 inline void Init(int n)
30 {
31 for (int i = 1; i <= n; ++i)
32 {
33 red[i] = 0;
34 head[i] = -1;
35 }
36 tot = 0;
37 }
38
39 ll dis[maxn];
40 int fa[maxn][DEG];
41 int deg[maxn];
42 int pre[maxn];
43
44 inline void BFS(int root)
45 {
46 queue<int>q;
47 dis[root] = 0;
48 deg[root] = 0;
49 fa[root][0] = root;
50 pre[root] = root;
51 q.push(root);
52 while (!q.empty())
53 {
54 int tmp = q.front();
55 q.pop();
56 for (int i = 1; i < DEG; ++i)
57 {
58 fa[tmp][i] = fa[fa[tmp][i - 1]][i - 1];
59 }
60 for (int i = head[tmp]; ~i; i = edge[i].nxt)
61 {
62 int v = edge[i].to;
63 ll w = edge[i].w;
64 if (v == fa[tmp][0]) continue;
65 deg[v] = deg[tmp] + 1;
66 fa[v][0] = tmp;
67 if (red[v])
68 {
69 pre[v] = v;
70 }
71 else
72 {
73 pre[v] = pre[tmp];
74 }
75 if (red[v])
76 {
77 dis[v] = 0;
78 }
79 else
80 {
81 dis[v] = dis[tmp] + w;
82 }
83 q.push(v);
84 }
85 }
86 }
87
88 inline int LCA(int u, int v)
89 {
90 if (deg[u] > deg[v]) swap(u, v);
91 int hu = deg[u], hv = deg[v];
92 int tu = u, tv = v;
93 for (int det = hv - hu, i = 0; det; det >>= 1, ++i)
94 {
95 if (det & 1)
96 {
97 tv = fa[tv][i];
98 }
99 }
100 if (tu == tv) return tu;
101 for (int i = DEG - 1; i >= 0; --i)
102 {
103 if (fa[tu][i] == fa[tv][i]) continue;
104 tu = fa[tu][i], tv = fa[tv][i];
105 }
106 return fa[tu][0];
107 }
108
109 int n, m, q, k;
110 int arr[maxn];
111
112 inline bool cmp(int a, int b)
113 {
114 return dis[a] > dis[b];
115 }
116
117 inline bool check(ll mid)
118 {
119 int root = arr[1];
120 int cnt = 0;
121 for (int i = 1; i <= k; ++i)
122 {
123 if (dis[arr[i]] > mid)
124 {
125 if (pre[root] != pre[arr[i]]) return false;
126 root = LCA(root, arr[i]);
127 cnt++;
128 }
129 }
130 if (cnt == 1 || cnt == 0) return true;
131 for (int i = 1; i <= k; ++i)
132 {
133 if (dis[arr[i]] > mid)
134 {
135 if (dis[arr[i]] - dis[root] > mid) return false;
136 }
137 }
138 return true;
139 }
140
141 inline void RUN()
142 {
143 int t;
144 scanf("%d", &t);
145 while (t--)
146 {
147 scanf("%d %d %d", &n, &m, &q);
148 Init(n);
149 for (int i = 1; i <= m; ++i)
150 {
151 int u;
152 scanf("%d", &u);
153 red[u] = 1;
154 }
155 for (int i = 1; i < n; ++i)
156 {
157 int u, v;
158 ll w;
159 scanf("%d %d %lld", &u, &v, &w);
160 addedge(u, v, w);
161 addedge(v, u, w);
162 }
163 BFS(1);
164 while (q--)
165 {
166 scanf("%d", &k);
167 for (int i = 1; i <= k; ++i)
168 {
169 scanf("%d", arr + i);
170 }
171 if (k == 1)
172 {
173 puts("0");
174 continue;
175 }
176 sort(arr + 1, arr + 1 + k, cmp);
177 ll l = 0;
178 ll r = INFLL;
179 ll ans = 0;
180 while (r - l >= 0)
181 {
182 ll mid = (r + l) >> 1;
183 if (check(mid))
184 {
185 r = mid - 1;
186 ans = mid;
187 }
188 else
189 {
190 l = mid + 1;
191 }
192 }
193 printf("%lld
", ans);
194 }
195 }
196 }
197
198 int main()
199 {
200 #ifdef LOCAL_JUDGE
201 freopen("Text.txt", "r", stdin);
202 #endif // LOCAL_JUDGE
203
204 RUN();
205
206 #ifdef LOCAL_JUDGE
207 fclose(stdin);
208 #endif // LOCAL_JUDGE
209 return 0;
210 }
View Code
C Halting Problem
题意:给出五种操作,机器从第一条命令开始,问是否能到n+1条命令。
思路:暴力,记录状态,若来到重复状态则输出No
1 #include<bits/stdc++.h>
2
3 using namespace std;
4
5 typedef long long ll;
6 const double eps = 1e-8;
7 const int INF = 0x3f3f3f3f;
8 const ll MOD = (int)1e9 + 7;
9 const int maxn = (int)1e4 + 10;
10
11 int n, num;
12 int vis[maxn][260];
13 struct node {
14 char op[10];
15 int v, k;
16 }arr[maxn];
17
18 inline void RUN()
19 {
20 int t;
21 scanf("%d", &t);
22 while (t--)
23 {
24 scanf("%d", &n);
25 for (int i = 1; i <= n; ++i)
26 {
27 for (int j = 0; j < 256; ++j)
28 {
29 vis[i][j] = 0;
30 }
31 }
32 int flag = true;
33 int s = 0;
34 int now = 1;
35 for (int i = 1; i <= n; ++i)
36 {
37 scanf("%s", arr[i].op);
38 if (strcmp(arr[i].op,"add") == 0)
39 {
40 scanf("%d", &arr[i].v);
41 arr[i].k = 0;
42 }
43 else
44 {
45 scanf("%d %d", &arr[i].v, &arr[i].k);
46 }
47 }
48 while (1)
49 {
50 if (now == n + 1)
51 {
52 flag = true;
53 break;
54 }
55 if (vis[now][s])
56 {
57 flag = false;
58 break;
59 }
60 vis[now][s]++;
61 if (strcmp(arr[now].op, "add") == 0)
62 {
63 s = (s + arr[now].v);
64 if (s >= 256)s -= 256;
65 now++;
66 }
67 else if (strcmp(arr[now].op, "beq") == 0)
68 {
69 if (s == arr[now].v)
70 {
71 now = arr[now].k;
72 }
73 else
74 {
75 now++;
76 }
77 }
78 else if (strcmp(arr[now].op, "bne") == 0)
79 {
80 if (s != arr[now].v)
81 {
82 now = arr[now].k;
83 }
84 else
85 {
86 now++;
87 }
88 }
89 else if (strcmp(arr[now].op, "blt") == 0)
90 {
91 if (s < arr[now].v)
92 {
93 now = arr[now].k;
94 }
95 else
96 {
97 now++;
98 }
99 }
100 else if (strcmp(arr[now].op, "bgt") == 0)
101 {
102 if (s > arr[now].v)
103 {
104 now = arr[now].k;
105 }
106 else
107 {
108 now++;
109 }
110 }
111 }
112 puts(flag ? "Yes" : "No");
113 }
114 }
115
116 int main()
117 {
118 #ifdef LOCAL_JUDGE
119 freopen("Text.txt", "r", stdin);
120 #endif // LOCAL_JUDGE
121
122 RUN();
123
124 #ifdef LOCAL_JUDGE
125 fclose(stdin);
126 #endif // LOCAL_JUDGE
127 return 0;
128 }
View Code
1 #include <bits/stdc++.h>
2 using namespace std;
3
4 #define N 100010
5 #define M N * 30
6 using ll = long long;
7 using pii = pair <int, int>;
8
9 int t, n;
10 set <int> s;
11 multiset <ll> mst;
12 map <pii, ll> mp;
13 int arr[N], p[N];
14 ll ans;
15
16 struct BIT
17 {
18 int a[N];
19 inline void update(int x)
20 {
21 for (int i = x; i <= n; i += i & -i)
22 ++a[i];
23 }
24 inline int query(int x)
25 {
26 int res = 0;
27 for (int i = x; i > 0; i -= i & -i)
28 res += a[i];
29 return res;
30 }
31 }bit;
32
33 struct chairman_tree
34 {
35 int T[N], L[M], R[M], C[M], tot;
36 inline int build(int l, int r)
37 {
38 int root = tot++;
39 C[root] = 0;
40 if (l < r)
41 {
42 int mid = (l + r) >> 1;
43 L[root] = build(l, mid);
44 R[root] = build(mid + 1, r);
45 }
46 return root;
47 }
48 inline int update(int root, int pos)
49 {
50 int newroot = tot++, tmp = newroot;
51 C[newroot] = C[root] + 1;
52 int l = 1, r = n;
53 while (l < r)
54 {
55 int mid = (l + r) >> 1;
56 if (pos <= mid)
57 {
58 L[newroot] = tot++; R[newroot] = R[root];
59 newroot = L[newroot], root = L[root];
60 r = mid;
61 }
62 else
63 {
64 L[newroot] = L[root], R[newroot] = tot++;
65 newroot = R[newroot], root = R[root];
66 l = mid + 1;
67 }
68 C[newroot] = C[root] + 1;
69 }
70 return tmp;
71 }
72 inline int query(int left_root, int right_root, int pos, int vis)
73 {
74 int l = 1, r = n, res = 0;
75 while (l < r)
76 {
77 int mid = (l + r) >> 1;
78 if (pos <= mid)
79 {
80 left_root = L[left_root];
81 right_root = L[right_root];
82 r = mid;
83 }
84 else
85 {
86 res += C[L[left_root]] - C[L[right_root]];
87 left_root = R[left_root];
88 right_root = R[right_root];
89 l = mid + 1;
90 }
91 }
92 if (vis) res += C[left_root] - C[right_root];
93 return res;
94 }
95 }ct;
96
97 inline void Init()
98 {
99 memset(bit.a, 0, sizeof bit.a); ct.tot = 0;
100 s.clear(), mst.clear(), mp.clear(); ans = 0;
101 s.emplace(0), s.emplace(n + 1);
102 ct.T[n + 1] = ct.build(1, n);
103 }
104
105 inline void Run()
106 {
107 for (scanf("%d", &t); t--; )
108 {
109 scanf("%d", &n); Init();
110 for (int i = 1; i <= n; ++i)
111 {
112 scanf("%d", arr + i);
113 bit.update(arr[i]);
114 ans += i - bit.query(arr[i]);
115 }
116 for (int i = 1; i <= n; ++i) scanf("%d", p + i);
117 for (int i = n; i >= 1; --i) ct.T[i] = ct.update(ct.T[i + 1], arr[i]);
118 mp[pii(1, n)] = ans; mst.insert(ans);
119 for (int i = 1; i <= n; ++i)
120 {
121 printf("%lld%c", ans, "
"[i == n]);
122 if (ans)
123 {
124 int id = int(ans ^ p[i]), l, r;
125 l = *(--s.upper_bound(id)) + 1;
126 r = *(s.upper_bound(id)) - 1; s.insert(id);
127 ll val = mp[pii(l, r)];
128 mst.erase(mst.lower_bound(val));
129 mp.erase(pii(l, r));
130 val -= id - l - ct.query(ct.T[l], ct.T[id], arr[id], 1);
131 if (id - l < r - id) // goto left
132 {
133 for (int j = l; j <= id; ++j)
134 val -= ct.query(ct.T[id + 1], ct.T[r + 1], arr[j], 0);
135 ll vall = 0, valr = 0;
136 for (int j = l + 1; j < id; ++j)
137 vall += j - l - ct.query(ct.T[l], ct.T[j], arr[j], 1);
138 valr = val - vall;
139 mst.insert(vall), mst.insert(valr);
140 mp[pii(l, id - 1)] = vall; mp[pii(id + 1, r)] = valr;
141 }
142 else // goto right
143 {
144 for (int j = id + 1; j <= r; ++j)
145 val -= id - l + 1 - ct.query(ct.T[l], ct.T[id + 1], arr[j], 1);
146 ll vall = 0, valr = 0;
147 for (int j = id + 1; j <= r; ++j)
148 valr += j - id - 1 - ct.query(ct.T[id + 1], ct.T[j], arr[j], 1);
149 vall = val - valr;
150 mst.insert(vall), mst.insert(valr);
151 mp[pii(l, id - 1)] = vall; mp[pii(id + 1, r)] = valr;
152 }
153 ans = *(mst.rbegin());
154 }
155 }
156 }
157 }
158
159 int main()
160 {
161 #ifdef LOCAL
162 freopen("Test.in", "r", stdin);
163 #endif
164
165 Run();
166 return 0;
167 }