10月补题
10.20
CF 732 E Sockets
心想队列少个log惨遭wa8.原因是合并要两个队列一起合.
直接set过。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <map> 5 #include <vector> 6 using namespace std; 7 const int maxn = 2e5 + 10; 8 int a[maxn], b[maxn]; 9 10 struct pt 11 { 12 int id, pw; 13 friend bool operator < (pt A, pt B) 14 { 15 if(A.pw != B.pw) return A.pw > B.pw; 16 return A.id < B.id; 17 } 18 } p[maxn]; 19 20 struct st 21 { 22 int id, a; 23 st(int _id = 0, int _a = 0): id(_id), a(_a) {} 24 friend bool operator < (st A, st B) 25 { 26 if(A.a != B.a) return A.a > B.a; 27 return A.id < B.id; 28 } 29 }; 30 31 map< int, vector<st> > s; 32 map< int, vector<st> > :: iterator it; 33 34 int main(void) 35 { 36 int n, m; 37 scanf("%d %d", &n, &m); 38 for(int i = 1; i <= n; i++) 39 { 40 scanf("%d", &p[i].pw); 41 p[i].id = i; 42 } 43 for(int i = 1; i <= m; i++) 44 { 45 int x; 46 scanf("%d", &x); 47 s[x].push_back(st(i, 0)); 48 } 49 sort(p + 1, p + 1 + n); 50 it = s.end(); 51 it--; 52 int c = 0, u = 0; 53 for(int i = 1; i <= n; i++) 54 { 55 if(s.begin() == s.end()) break; 56 while((*it).first > p[i].pw) 57 { 58 int nxt = ((*it).first + 1) / 2; 59 while(!(*it).second.empty()) 60 { 61 (*(*it).second.rbegin()).a++; 62 s[nxt].push_back(*(*it).second.rbegin()); 63 (*it).second.pop_back(); 64 } 65 s.erase(it); 66 if(s.begin() == s.end()) break; 67 it = s.end(); 68 it--; 69 sort((*it).second.begin(), (*it).second.end()); 70 } 71 if(s.begin() == s.end()) break; 72 if((*it).first == p[i].pw && !(*it).second.empty()) 73 { 74 int id = (*(*it).second.rbegin()).id; 75 b[p[i].id] = id; 76 c++; 77 a[id] = (*(*it).second.rbegin()).a; 78 u += a[id]; 79 (*it).second.pop_back(); 80 } 81 } 82 printf("%d %d\n", c, u); 83 for(int i = 1; i <= m; i++) printf("%d ", a[i]); puts(""); 84 for(int i = 1; i <= n; i++) printf("%d ", b[i]); puts(""); 85 return 0; 86 }
CF 732 F Tourist Reform
用了非常麻烦的做法。
先Tarjan,边双内跑欧拉回路,以最大的分量为rt,桥边连fa。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <stack> 5 #include <algorithm> 6 #include <vector> 7 using namespace std; 8 const int maxn = 4e5 + 10; 9 10 // edge 11 int cnt, h[maxn]; 12 struct edge 13 { 14 int id, flag; 15 int to, pre; 16 } e[maxn<<1]; 17 void add(int from, int to, int id) 18 { 19 cnt++; 20 e[cnt].pre = h[from]; 21 e[cnt].to = to; 22 e[cnt].id = id; 23 e[cnt].flag = 1; 24 h[from] = cnt; 25 } 26 27 // BCC 28 stack<int> S; 29 int dfs_clock, dfn[maxn], low[maxn]; 30 int bcc_cnt, bccno[maxn]; 31 32 void dfs(int u, int fa) 33 { 34 dfn[u] = low[u] = ++dfs_clock; 35 S.push(u); 36 bool flag = false; 37 for(int i = h[u]; i; i = e[i].pre) 38 { 39 int v = e[i].to; 40 if(v == fa && !flag) {flag = true; continue;} 41 if(!dfn[v]) 42 { 43 dfs(v, u); 44 low[u] = min(low[u], low[v]); 45 } 46 else if(!bccno[v]) low[u] = min(low[u], dfn[v]); 47 } 48 49 if(low[u] == dfn[u]) 50 { 51 bcc_cnt++; 52 while(1) 53 { 54 int x = S.top(); S.pop(); 55 bccno[x] = bcc_cnt; 56 if(x == u) break; 57 } 58 } 59 } 60 61 void find_bcc(int n) 62 { 63 memset(dfn, 0, sizeof(dfn)); 64 memset(bccno, 0, sizeof(bccno)); 65 dfs_clock = bcc_cnt = 0; 66 for(int i = 1; i <= n; i++) if(!dfn[i]) dfs(i, 0); 67 } 68 69 // solve 70 int hh[maxn], deg[maxn]; 71 int ansu[maxn], ansv[maxn]; 72 int vis[maxn], odd[maxn]; 73 typedef pair<int, int> pii; 74 vector<pii> g[maxn]; 75 76 void dfs1(int x) 77 { 78 for(int & i = hh[x]; i; ) 79 { 80 int ii = i, to = e[i].to, id = e[i].id, flag = e[i].flag; 81 i = e[i].pre; 82 if(bccno[to] != bccno[x]) g[bccno[x]].push_back(pii(to, id)); 83 if(!flag) continue; 84 if(ii % 2) e[ii+1].flag = 0; 85 else e[ii-1].flag = 0; 86 if(bccno[to] == bccno[x]) 87 { 88 if(ansv[id] != to) swap(ansu[id], ansv[id]); 89 dfs1(to); 90 } 91 } 92 } 93 94 void dfs2(int x, int fa) 95 { 96 int sz = g[x].size(); 97 for(int i = 0; i < sz; i++) 98 { 99 int to = g[x][i].first, id = g[x][i].second; 100 if(bccno[to] == fa) continue; 101 if(ansu[id] != to) swap(ansu[id], ansv[id]); 102 dfs2(bccno[to], x); 103 } 104 } 105 106 int sz[maxn]; 107 int main(void) 108 { 109 int n, m; 110 scanf("%d %d", &n, &m); 111 for(int i = 1; i <= m; i++) 112 { 113 scanf("%d %d", ansu + i, ansv + i); 114 add(ansu[i], ansv[i], i), add(ansv[i], ansu[i], i); 115 } 116 find_bcc(n); 117 for(int i = 1; i <= n; i++) 118 { 119 for(int j = h[i]; j; j = e[j].pre) 120 if(bccno[e[j].to] == bccno[i]) deg[i]++; 121 if(deg[i] % 2) odd[bccno[i]]++; 122 } 123 memcpy(hh, h, sizeof(hh)); 124 int ans = 0, p; 125 for(int i = 1; i <= n; i++) 126 { 127 sz[bccno[i]]++; 128 if(sz[bccno[i]] > ans) ans = sz[bccno[i]], p = bccno[i]; 129 if(vis[bccno[i]]) continue; 130 if(odd[bccno[i]] && deg[i] % 2 == 0) continue; 131 vis[bccno[i]] = 1, dfs1(i); 132 } 133 dfs2(p, 0); 134 printf("%d\n", ans); 135 for(int i = 1; i <= m; i++) printf("%d %d\n", ansu[i], ansv[i]); 136 return 0; 137 }
10.21
hihocoder 1384 Genius ACM
向Q学了复杂度。两个log卡不过。学习了csy的一个log卡过了。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 typedef long long LL; 6 typedef pair<LL, int> pii; 7 const int maxn = 5e5 + 10; 8 LL k, P[maxn], tmp[maxn]; 9 pii t[maxn]; 10 int n, m; 11 12 bool check(int l, int sz) 13 { 14 for(int i = l; i < l + sz; i++) tmp[i-l] = P[i]; 15 sort(tmp, tmp + sz); 16 LL sum = 0; 17 for(int i = 0; i < min(m, sz / 2); i++) sum += (tmp[i] - tmp[sz-i-1]) * (tmp[i] - tmp[sz-i-1]); 18 return sum <= k; 19 } 20 21 int main(void) 22 { 23 int T; 24 scanf("%d", &T); 25 while(T--) 26 { 27 scanf("%d %d %lld", &n, &m, &k); 28 for(int i = 1; i <= n; i++) scanf("%lld", P + i); 29 int ans = 0; 30 for(int l = 1; l <= n; ) 31 { 32 int len = 0; 33 while((1 << len) <= n - l + 1 && check(l, 1 << len)) len++; 34 int L = l + (1 << (len - 1)) - 1, R = min(n, l + (1 << len) - 1); 35 int sz = R - l + 1; 36 for(int i = l; i <= R; i++) t[i-l] = pii(P[i], i); 37 sort(t, t + sz); 38 while(L < R) 39 { 40 int M = R - (R - L) / 2; 41 int p1 = 0, p2 = sz - 1; 42 LL sum = 0; 43 for(int i = 0; i < m; i++) 44 { 45 while(p1 < sz && t[p1].second > M) p1++; 46 while(p2 >= 0 && t[p2].second > M) p2--; 47 if(p1 < p2) sum += (t[p1].first - t[p2].first) * (t[p1].first - t[p2].first), p1++, p2--; 48 else break; 49 } 50 if(sum <= k) L = M; else R = M - 1; 51 } 52 ans++, l = L + 1; 53 } 54 printf("%d\n", ans); 55 } 56 return 0; 57 }
hihocoder 1386 Pick Your Players
巧妙的是captain可以先sort再特殊处理下第一个。
然后刷表就可以了。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int INF = 1e9; 7 8 struct player 9 { 10 char pos; 11 int val, cost; 12 friend bool operator < (player A, player B) 13 { 14 return A.val > B.val; 15 } 16 } p[505]; 17 18 int f1[2][6][6][4][1001], f2[2][6][6][4][1001]; 19 int main(void) 20 { 21 int T; 22 scanf("%d", &T); 23 while(T--) 24 { 25 int N, L; 26 scanf("%d", &N); 27 for(int i = 1; i <= N; i++) 28 { 29 char s[22]; 30 scanf("%s", s); 31 p[i].pos = s[0]; 32 scanf("%d %d", &p[i].val, &p[i].cost); 33 } 34 scanf("%d", &L); 35 sort(p + 1, p + 1 + N); 36 37 memset(f1, 0, sizeof(f1)); 38 memset(f2, 0, sizeof(f2)); 39 f2[0][0][0][0][0] = 1; 40 41 for(int i = 1; i <= N; i++) 42 for(int g = 1; g >= 0; g--) 43 for(int d = 5; d >= 0; d--) 44 for(int m = 5; m >= 0; m--) 45 for(int f = 3; f >= 0; f--) 46 for(int c = L - p[i].cost; c >= 0; c--) 47 { 48 if(!f2[g][d][m][f][c]) continue; 49 50 if(g == 1 && p[i].pos == 'G') continue; 51 if(d == 5 && p[i].pos == 'D') continue; 52 if(m == 5 && p[i].pos == 'M') continue; 53 if(f == 3 && p[i].pos == 'F') continue; 54 55 int ng = g, nd = d, nm = m, nf = f, nc = c + p[i].cost; 56 57 if(p[i].pos == 'G') ng++; 58 if(p[i].pos == 'D') nd++; 59 if(p[i].pos == 'M') nm++; 60 if(p[i].pos == 'F') nf++; 61 62 if(ng + nd + nm + nf > 11) continue; 63 64 if(g || d || m || f) 65 { 66 if(f1[ng][nd][nm][nf][nc] > f1[g][d][m][f][c] + p[i].val) continue; 67 if(f1[ng][nd][nm][nf][nc] == f1[g][d][m][f][c] + p[i].val) f2[ng][nd][nm][nf][nc] += f2[g][d][m][f][c]; 68 else f1[ng][nd][nm][nf][nc] = f1[g][d][m][f][c] + p[i].val, f2[ng][nd][nm][nf][nc] = f2[g][d][m][f][c]; 69 if(f2[ng][nd][nm][nf][nc] > INF) f2[ng][nd][nm][nf][nc] = INF; 70 } 71 72 else 73 { 74 if(f1[ng][nd][nm][nf][nc] > f1[g][d][m][f][c] + p[i].val * 2) continue; 75 if(f1[ng][nd][nm][nf][nc] == f1[g][d][m][f][c] + p[i].val * 2) f2[ng][nd][nm][nf][nc] += f2[g][d][m][f][c]; 76 else f1[ng][nd][nm][nf][nc] = f1[g][d][m][f][c] + p[i].val * 2, f2[ng][nd][nm][nf][nc] = f2[g][d][m][f][c]; 77 if(f2[ng][nd][nm][nf][nc] > INF) f2[ng][nd][nm][nf][nc] = INF; 78 } 79 } 80 81 82 int max_val = -1, min_cost = INF, ans = 0; 83 for(int c = 0; c <= L; c++) 84 for(int d = 3; d <= 5; d++) 85 for(int m = 2; m <= 5; m++) 86 for(int f = 1; f <= 3; f++) 87 { 88 if(d + m + f != 10) continue; 89 if(!f2[1][d][m][f][c]) continue; 90 if(f1[1][d][m][f][c] > max_val) 91 { 92 max_val = f1[1][d][m][f][c]; 93 min_cost = c; 94 ans = f2[1][d][m][f][c]; 95 } 96 else if(f1[1][d][m][f][c] == max_val && c == min_cost) 97 { 98 ans = ans + f2[1][d][m][f][c]; 99 if(ans > INF) ans = INF; 100 } 101 } 102 103 printf("%d %d %d\n", max_val, min_cost, ans); 104 } 105 return 0; 106 }
10.22
hihocoder 1387 A Research on "The Hundred Family Surnames"
预处理LCA。然后维护每种颜色的最长链。询问两条链合并下。
如果一种颜色有多条最长链,其实是没有影响的。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <map> 6 using namespace std; 7 typedef pair<int, int> pii; 8 const int maxn = 1e5 + 10; 9 map<string, int> M; 10 11 12 // edge 13 int cnt, h[maxn]; 14 struct edge 15 { 16 int to, pre; 17 } e[maxn<<1]; 18 void init() 19 { 20 cnt = 0; 21 memset(h, 0, sizeof(h)); 22 } 23 void add(int from, int to) 24 { 25 cnt++; 26 e[cnt].pre = h[from]; 27 e[cnt].to = to; 28 h[from] = cnt; 29 } 30 31 32 33 // LCA 34 int dep[maxn]; 35 int anc[maxn][33]; 36 void dfs(int x, int fa) 37 { 38 for(int i = h[x]; i; i = e[i].pre) 39 { 40 int to = e[i].to; 41 if(to == fa) continue; 42 dep[to] = dep[x] + 1; 43 anc[to][0] = x; 44 dfs(to, x); 45 } 46 } 47 48 void LCA_init(int n) 49 { 50 for(int j = 1; (1 << j) < n; j++) 51 for(int i = 1; i <= n; i++) if(anc[i][j-1]) 52 anc[i][j] = anc[anc[i][j-1]][j-1]; 53 } 54 55 int LCA(int u, int v) 56 { 57 int log; 58 if(dep[u] < dep[v]) swap(u, v); 59 for(log = 0; (1 << log) < dep[u]; log++); 60 for(int i = log; i >= 0; i--) 61 if(dep[u] - (1<<i) >= dep[v]) u = anc[u][i]; 62 if(u == v) return u; 63 for(int i = log; i >= 0; i--) 64 if(anc[u][i] && anc[u][i] != anc[v][i]) 65 u = anc[u][i], v = anc[v][i]; 66 return anc[u][0]; 67 } 68 69 int id[maxn]; 70 pii p[maxn]; 71 int main(void) 72 { 73 int n, m; 74 while(~scanf("%d %d", &n, &m)) 75 { 76 int tot = 0; 77 M.clear(); 78 for(int i = 1; i <= n; i++) 79 { 80 char str[111]; 81 scanf("%s", str); 82 string s(str); 83 if(!M[s]) M[s] = ++tot; 84 id[i] = M[s]; 85 } 86 init(); 87 for(int i = 1; i < n; i++) 88 { 89 int u, v; 90 scanf("%d %d", &u, &v); 91 add(u, v), add(v, u); 92 } 93 94 dfs(1, 0); 95 LCA_init(n); 96 97 memset(p, 0, sizeof(p)); 98 for(int i = 1; i <= n; i++) 99 { 100 int & u = p[id[i]].first, & v = p[id[i]].second; 101 if(!u) u = i; 102 else if(!v) v = i; 103 else 104 { 105 int L = dep[u] + dep[v] - dep[LCA(u, v)] - dep[LCA(u, v)]; 106 int L1 = dep[u] + dep[i] - dep[LCA(u, i)] - dep[LCA(u, i)]; 107 int L2 = dep[i] + dep[v] - dep[LCA(i, v)] - dep[LCA(i, v)]; 108 if(L1 >= L && L1 >= L2) v = i; 109 else if(L2 >= L && L2 >= L1) u = i; 110 } 111 } 112 113 while(m--) 114 { 115 char aa[111], bb[111]; 116 scanf("%s %s", aa, bb); 117 string a(aa), b(bb); 118 if(!M[a] || !M[b]) {puts("-1"); continue;} 119 int u1 = p[M[a]].first, v1 = p[M[a]].second; 120 int u2 = p[M[b]].first, v2 = p[M[b]].second; 121 int ans = dep[u1] + dep[u2] - dep[LCA(u1, u2)] - dep[LCA(u1, u2)]; 122 if(v1) ans = max(ans, dep[v1] + dep[u2] - dep[LCA(v1, u2)] - dep[LCA(v1, u2)]); 123 if(v2) ans = max(ans, dep[u1] + dep[v2] - dep[LCA(u1, v2)] - dep[LCA(u1, v2)]); 124 if(v1 && v2) ans = max(ans, dep[v1] + dep[v2] - dep[LCA(v1, v2)] - dep[LCA(v1, v2)]); 125 printf("%d\n", ans + 1); 126 } 127 } 128 return 0; 129 }
hihocoder 1389 Sewage Treatment
卡了半辈子的迷之复杂度。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <queue> 6 #include <cmath> 7 using namespace std; 8 const int INF = 1e9; 9 const int maxn = 222; 10 int lv[maxn], it[maxn]; 11 int cnt, h[maxn]; 12 13 struct edge 14 { 15 int to, pre, cap; 16 } e[44444]; 17 18 void init() 19 { 20 memset(h, -1, sizeof(h)); 21 cnt = 0; 22 } 23 24 void add(int from, int to, int cap) 25 { 26 e[cnt].pre = h[from]; 27 e[cnt].to = to; 28 e[cnt].cap = cap; 29 h[from] = cnt; 30 cnt++; 31 } 32 33 void ad(int from, int to, int cap) 34 { 35 add(from, to, cap); 36 add(to, from, 0); 37 } 38 39 void bfs(int s) 40 { 41 memset(lv, -1, sizeof(lv)); 42 queue<int> q; 43 lv[s] = 0; 44 q.push(s); 45 while(!q.empty()) 46 { 47 int v = q.front(); q.pop(); 48 for(int i = h[v]; i >= 0; i = e[i].pre) 49 { 50 int cap = e[i].cap, to = e[i].to; 51 if(cap > 0 && lv[to] < 0) 52 { 53 lv[to] = lv[v] + 1; 54 q.push(to); 55 } 56 } 57 } 58 } 59 60 int dfs(int v, int t, int f) 61 { 62 if(v == t) return f; 63 for(int &i = it[v]; i >= 0; i = e[i].pre) 64 { 65 int &cap = e[i].cap, to = e[i].to; 66 if(cap > 0 && lv[v] < lv[to]) 67 { 68 int d = dfs(to, t, min(f, cap)); 69 if(d > 0) 70 { 71 cap -= d; 72 e[i^1].cap += d; 73 return d; 74 } 75 } 76 } 77 return 0; 78 } 79 80 int Dinic(int s, int t) 81 { 82 int flow = 0; 83 while(1) 84 { 85 bfs(s); 86 if(lv[t] < 0) return flow; 87 memcpy(it, h, sizeof(it)); 88 int f; 89 while((f = dfs(s, t, INF)) > 0) flow += f; 90 } 91 } 92 93 struct E 94 { 95 int i, j, dist; 96 friend bool operator < (E A, E B) 97 { 98 return A.dist < B.dist; 99 } 100 } EE[11111]; 101 102 int xi[111], yi[111], si[111]; 103 int xj[111], yj[111]; 104 int dist[11111]; 105 double tmp[11111]; 106 int main(void) 107 { 108 int n, m; 109 while(~scanf("%d %d", &n, &m) && n) 110 { 111 int sum = 0; 112 for(int i = 1; i <= n; i++) scanf("%d %d %d", xi + i, yi + i, si + i), sum += si[i]; 113 for(int i = 1; i <= m; i++) scanf("%d %d", xj + i, yj + i); 114 int tot = 0; 115 for(int i = 1; i <= n; i++) 116 for(int j = 1; j <= m; j++) 117 dist[tot] = (xi[i] - xj[j]) * (xi[i] - xj[j]) + (yi[i] - yj[j]) * (yi[i] - yj[j]), 118 EE[tot].i = i, EE[tot].j = j, EE[tot].dist = dist[tot], tot++; 119 sort(dist, dist + tot); 120 sort(EE, EE + tot); 121 double ans = INF; 122 for(int i = 0; i < tot; i++) 123 { 124 int l = sum / m, r, mid; 125 if(!i) r = 40000; 126 else r = tmp[i-1]; 127 if(l * sqrt(sqrt(dist[i])) > ans) break; 128 while(l < r) 129 { 130 init(); 131 mid = l + (r - l) / 2; 132 int S = n + m + 1, T = S + 1; 133 for(int j = 1; j <= n; j++) ad(S, j, si[j]); 134 for(int j = 1; j <= m; j++) ad(n + j, T, mid); 135 for(int j = 0; j <= i; j++) ad(EE[j].i, n + EE[j].j, INF); 136 if(sum == Dinic(S, T)) r = mid; 137 else l = mid + 1; 138 } 139 tmp[i] = r; 140 ans = min(ans, r * sqrt(sqrt(dist[i]))); 141 } 142 printf("%.0f\n", ans); 143 } 144 return 0; 145 }