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 }
Aguin

 

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 }
Aguin

 

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 }
Aguin

 

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 }
Aguin

 

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 }
Aguin

 

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 }
Aguin

 

posted @ 2016-10-21 20:46  Aguin  阅读(238)  评论(0编辑  收藏  举报