2017 Multi-University Training Contest - Team 1

半面数学 半面卡常

 

1001 Add More Zero

水题不写。

 

1002 Balala Power!

贪心,注意0不能首位。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef long long LL;
 7 const LL mod = 1e9 + 7;
 8 const int maxn = 2e5 + 10;
 9 int d[26][maxn], sz[26], fir[26], id[26], vis[26];
10 char s[maxn];
11 
12 bool larger(int i, int j)
13 {
14     if(sz[i] > sz[j]) return true;
15     if(sz[i] < sz[j]) return false;
16     for(int k = sz[i]; k >= 0; k--)
17         if(d[i][k] != d[j][k]) return d[i][k] > d[j][k];
18     return false;
19 }
20 
21 int main(void)
22 {
23     int n, kase = 0;
24     while(~scanf("%d", &n))
25     {
26         memset(d, 0, sizeof(d));
27         memset(sz, 0, sizeof(sz));
28         memset(fir, 0, sizeof(fir));
29         memset(vis, 0, sizeof(vis));
30         memset(id, -1, sizeof(id));
31         for(int i = 1; i <= n; i++)
32         {
33             scanf("%s", s + 1);
34             int l = strlen(s + 1);
35             if(l != 1) fir[s[1]-'a'] = 1;
36             for(int j = l; j; j--)
37             {
38                 d[s[j]-'a'][l-j]++;
39                 sz[s[j]-'a'] = max(sz[s[j]-'a'], l-j);
40                 vis[s[j]-'a'] = 1;
41             }
42         }
43         for(int c = 0; c < 26; c++)
44             for(int i = 0; i <= sz[c]; i++)
45                 if(d[c][i] >= 26) d[c][i+1] += d[c][i] / 26, d[c][i] %= 26, sz[c] = max(sz[c], i + 1);
46         int cnt = 0;
47         for(int i = 0; i < 26; i++) cnt += vis[i];
48         if(cnt == 26)
49         {
50             int p = -1;
51             for(int i = 0; i < 26; i++)
52             {
53                 if(fir[i]) continue;
54                 if(p == -1 || larger(p, i)) p = i;
55             }
56             id[p] = 0;
57             for(int i = 1; i <= 25; i++)
58             {
59                 p = -1;
60                 for(int j = 0; j < 26; j++)
61                 {
62                     if(id[j] != -1) continue;
63                     if(p == -1 || larger(p, j)) p = j;
64                 }
65                 id[p] = i;
66             }
67         }
68         else
69         {
70             for(int i = 25; i >= 26 - cnt; i--)
71             {
72                 int p = -1;
73                 for(int j = 0; j < 26; j++)
74                 {
75                     if(id[j] != -1) continue;
76                     if(p == -1 || larger(j, p)) p = j;
77                 }
78                 id[p] = i;
79             }
80         }
81         LL ans = 0;
82         for(int i = 0; i < 26; i++)
83         {
84             if(!vis[i]) continue;
85             LL base = 1;
86             for(int j = 0; j <= sz[i]; j++) ans = (ans + id[i] * base % mod * d[i][j]) % mod, base = base * 26 % mod;
87         }
88         printf("Case #%d: %lld\n", ++kase, ans);
89     }
90     return 0;
91 }
Aguin

 

1003 Colorful Tree

其实和虚树没什么关系 考虑统计不经过颜色c的路径 端点一定在一些联通块里

对于一个颜色c的节点 遍历子树时把遇到的含有颜色c的子树扣掉就是这个联通块的大小

但是还需要注意的是还会有一个包含root的联通块要单独考虑

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <unordered_map>
 6 #include <stack>
 7 using namespace std;
 8 typedef long long LL;
 9 const int maxn = 2e5 + 10;
10 int vis[maxn], c[maxn];
11 unordered_map< int, stack<int> > st;
12 
13 int cnt, h[maxn];
14 struct edge
15 {
16     int to, pre;
17 } e[maxn<<1];
18 void add(int from, int to)
19 {
20     cnt++;
21     e[cnt].pre = h[from];
22     e[cnt].to = to;
23     h[from] = cnt;
24 }
25 
26 LL ans;
27 int sz[maxn], num[maxn], rt[maxn];
28 void dfs(int x, int f)
29 {
30     st[c[x]].push(x);
31     sz[x] = 1, num[x] = 0;
32     for(int i = h[x]; i; i = e[i].pre)
33     {
34         int to = e[i].to;
35         if(to == f) continue;
36         dfs(to, x);
37         sz[x] += sz[to];
38         ans -= (LL) (sz[to] - num[x]) * (sz[to] - num[x] - 1) / 2;
39         num[x] = 0;
40     }
41     st[c[x]].pop();
42     if(st[c[x]].empty()) rt[c[x]] += sz[x];
43     else num[st[c[x]].top()] += sz[x];
44 }
45 
46 int main(void)
47 {
48     int n, kase = 0;
49     while(~scanf("%d", &n))
50     {
51         st.clear();
52         cnt = 0;
53         for(int i = 1; i <= n; i++) h[i] = vis[i] = rt[i] = 0;
54         for(int i = 1; i <= n; i++) scanf("%d", c + i), vis[c[i]] = 1;
55         for(int i = 1; i < n; i++)
56         {
57             int u, v;
58             scanf("%d %d", &u, &v);
59             add(u, v), add(v, u);
60         }
61         ans = 0;
62         dfs(1, 0);
63         for(int i = 1; i <= n; i++) if(vis[i]) ans += (LL) n * (n - 1) / 2 - (LL) (sz[1] - rt[i]) * (sz[1] - rt[i] - 1) / 2;
64         printf("Case #%d: %lld\n", ++kase, ans);
65     }
66     return 0;
67 }
Aguin

场上卡了很久的点分治,大概是每次直接统计经过当前根rt的边的贡献

需要算哪些颜色贡献计算一次,哪些计算两次

遍历次数比较多,加读入挂才过

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 using namespace std;
  6 
  7 // fastIO
  8 namespace fastIO {
  9     #define BUF_SIZE 100000
 10     //fread -> read
 11     bool IOerror = 0;
 12     inline char nc() {
 13         static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
 14         if(p1 == pend) {
 15             p1 = buf;
 16             pend = buf + fread(buf, 1, BUF_SIZE, stdin);
 17             if(pend == p1) {
 18                 IOerror = 1;
 19                 return -1;
 20             }
 21         }
 22         return *p1++;
 23     }
 24     inline bool blank(char ch) {
 25         return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
 26     }
 27     inline void read(int &x) {
 28         char ch;
 29         while(blank(ch = nc()));
 30         if(IOerror)
 31             return;
 32         for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
 33     }
 34     #undef BUF_SIZE
 35 };
 36 using namespace fastIO;
 37 
 38 typedef long long LL;
 39 const int maxn = 2e5 + 10;
 40 int vis[maxn], c[maxn];
 41 
 42 // edge
 43 int cnt, h[maxn];
 44 struct edge
 45 {
 46     int to, pre;
 47 } e[maxn<<1];
 48 
 49 void add(int from, int to)
 50 {
 51     cnt++;
 52     e[cnt].pre = h[from];
 53     e[cnt].to = to;
 54     h[from] = cnt;
 55 }
 56 
 57 // tree
 58 int sz[maxn];
 59 void Size(int x, int f)
 60 {
 61     sz[x] = 1;
 62     int tmp = 0;
 63     for(int i = h[x]; i; i = e[i].pre)
 64     {
 65         int to = e[i].to;
 66         if(to == f || vis[to]) continue;
 67         Size(to, x);
 68         sz[x] += sz[to];
 69     }
 70 }
 71 
 72 int rt, M;
 73 void Root(int r, int x, int f)
 74 {
 75     int tmp = 0;
 76     for(int i = h[x]; i; i = e[i].pre)
 77     {
 78         int to = e[i].to;
 79         if(to == f || vis[to]) continue;
 80         Root(r, to, x);
 81         tmp = max(tmp, sz[to]);
 82     }
 83     tmp = max(tmp, sz[r] - sz[x]);
 84     if(tmp < M) M = tmp, rt = x;
 85 }
 86 
 87 LL ans;
 88 int num[maxn];
 89 void dfs(int x, int rt, int f)
 90 {
 91     sz[x] = 1;
 92     for(int i = h[x]; i; i = e[i].pre)
 93     {
 94         int to = e[i].to;
 95         if(to == f || vis[to]) continue;
 96         dfs(to, rt, x);
 97         sz[x] += sz[to];
 98     }
 99     if(f == rt) ans += (LL) sz[x] * sz[rt];
100 }
101 
102 int c_sz[maxn];
103 void dfs1(int x, int szr, int f)
104 {
105     num[c[x]]++;
106     if(num[c[x]] == 1) ans += (LL) sz[x] * (szr - c_sz[c[x]]);
107     for(int i = h[x]; i; i = e[i].pre)
108     {
109         int to = e[i].to;
110         if(to == f || vis[to]) continue;
111         dfs1(to, szr, x);
112     }
113     num[c[x]]--;
114 }
115 void dfs2(int x, int f)
116 {
117     num[c[x]]++;
118     if(num[c[x]] == 1) c_sz[c[x]] += sz[x];
119     for(int i = h[x]; i; i = e[i].pre)
120     {
121         int to = e[i].to;
122         if(to == f || vis[to]) continue;
123         dfs2(to, x);
124     }
125     num[c[x]]--;
126 }
127 void dfs3(int x, int f)
128 {
129     num[c[x]]++;
130     if(num[c[x]] == 1) c_sz[c[x]] -= sz[x];
131     for(int i = h[x]; i; i = e[i].pre)
132     {
133         int to = e[i].to;
134         if(to == f || vis[to]) continue;
135         dfs3(to, x);
136     }
137     num[c[x]]--;
138 }
139 
140 void solve(int x)
141 {
142     M = maxn;
143     Size(x, 0);
144     Root(x, x, 0);
145     vis[rt] = 1;
146 
147     dfs(rt, rt, 0);
148     num[c[rt]]++;
149     for(int i = h[rt]; i; i = e[i].pre)
150     {
151         int to = e[i].to;
152         if(vis[to]) continue;
153         dfs1(to, sz[rt] - sz[to], rt);
154         dfs2(to, rt);
155     }
156     for(int i = h[rt]; i; i = e[i].pre)
157     {
158         int to = e[i].to;
159         if(vis[to]) continue;
160         dfs3(to, rt);
161     }
162     num[c[rt]]--;
163 
164     for(int i = h[rt]; i; i = e[i].pre)
165     {
166         int to = e[i].to;
167         if(vis[to]) continue;
168         solve(to);
169     }
170 }
171 
172 int main(void)
173 {
174     // int size = 256 << 20; // 256MB
175     // char *p = (char*)malloc(size) + size;
176     // __asm__("movl %0, %%esp\n" :: "r"(p));
177 
178     // freopen("data.txt", "r", stdin);
179     // freopen("ygy.txt", "w", stdout);
180 
181     int n, kase = 0;
182     while(read(n), !IOerror)
183     {
184         for(int i = 1; i <= n; i++) read(c[i]);
185         cnt = 0;
186         for(int i = 1; i <= n; i++) h[i] = vis[i] = 0;
187         for(int i = 1; i < n; i++)
188         {
189             int u, v;
190             read(u), read(v);
191             add(u, v), add(v, u);
192         }
193         ans = 0; solve(1);
194         printf("Case #%d: %lld\n", ++kase, ans);
195     }
196     return 0;
197 }
Aguin

 

1004 Division Game

1005 Expectation Division

1006 Function

观察到置换分解后只能映射到因子长度的环上

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <vector>
 5 using namespace std;
 6 typedef long long LL;
 7 const LL mod = 1e9 + 7;
 8 const int maxn = 1e5 + 10;
 9 int a[maxn], b[maxn];
10 int visa[maxn], visb[maxn];
11 int numa[maxn], numb[maxn];
12 vector<int> fac[maxn];
13 
14 int main(void)
15 {
16     for(int i = 1; i < maxn; i++)
17         for(int j = i; j < maxn; j += i)
18             fac[j].push_back(i);
19     int n, m, kase= 0;
20     while(~scanf("%d %d", &n, &m))
21     {
22         for(int i = 0; i < n; i++) scanf("%d", a + i);
23         for(int i = 0; i < m; i++) scanf("%d", b + i);
24         memset(visa, 0, sizeof(visa));
25         memset(visb, 0, sizeof(visb));
26         memset(numa, 0, sizeof(numa));
27         memset(numb, 0, sizeof(numb));
28         for(int i = 0; i < n; i++)
29         {
30             if(visa[i]) continue;
31             int p = i, cnt = 0;
32             while(!visa[p]) visa[p] = 1, cnt++, p = a[p];
33             numa[cnt]++;
34         }
35         for(int i = 0; i < m; i++)
36         {
37             if(visb[i]) continue;
38             int p = i, cnt = 0;
39             while(!visb[p]) visb[p] = 1, cnt++, p = b[p];
40             numb[cnt]++;
41         }
42         LL ans = 1;
43         for(int i = 1; i <= n; i++)
44         {
45             if(!numa[i]) continue;
46             LL tmp = 0;
47             for(int j = 0; j < fac[i].size(); j++) tmp = (tmp + (LL) numb[fac[i][j]] * fac[i][j]) % mod;
48             for(int j = 0; j < numa[i]; j++) ans = ans * tmp % mod;
49         }
50         printf("Case #%d: %lld\n", ++kase, ans);
51     }
52     return 0;
53 }
Aguin

 

1007 Gear Up

不好写……

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <vector>
  4 #include <algorithm>
  5 #include <cmath>
  6 using namespace std;
  7 const int maxn = 1e5 + 10;
  8 const int INF = 1e9;
  9 vector<int> vec[maxn];
 10 
 11 int log2(int x)
 12 {
 13     int cnt = 0;
 14     while(x >= 2) x >>= 1, cnt++;
 15     return cnt;
 16 }
 17 
 18 // edge
 19 int cnt, h[maxn];
 20 struct edge
 21 {
 22     int to, pre;
 23 } e[maxn<<1];
 24 void add(int from, int to)
 25 {
 26     cnt++;
 27     e[cnt].pre = h[from];
 28     e[cnt].to = to;
 29     h[from] = cnt;
 30 }
 31 
 32 // UF
 33 int fa[maxn];
 34 int Find(int x)
 35 {
 36     return fa[x] == x ? x : fa[x] = Find(fa[x]);
 37 }
 38 void Union(int x, int y)
 39 {
 40     x = Find(x);
 41     y = Find(y);
 42     if(x != y) fa[y] = x;
 43 }
 44 
 45 // dfs
 46 int dfs_clock;
 47 int r[maxn], w[maxn];
 48 int vis[maxn], op[maxn], rt[maxn];
 49 int L1[maxn], R1[maxn], L2[maxn], R2[maxn], rl[maxn], rr[maxn];
 50 void dfs(int x, int o, int root)
 51 {
 52     rt[x] = root;
 53     L2[x] = ++dfs_clock;
 54     int ww = w[dfs_clock];
 55     vis[x] = 1, op[x] = o;
 56     vector<int> tmp = vec[Find(x)];
 57     vec[Find(x)].clear();
 58     int sz = tmp.size();
 59     for(int i = 0; i < sz; i++)
 60     {
 61         int to = tmp[i];
 62         if(to == x) continue;
 63         w[dfs_clock + 1] = ww, dfs(to, 2, root);
 64     }
 65     R2[x] = dfs_clock, L1[x] = R2[x] + 1;
 66     for(int i = h[x]; i; i = e[i].pre)
 67     {
 68         int to = e[i].to;
 69         if(vis[to]) continue;
 70         w[dfs_clock + 1] = ww + r[x] - r[to], dfs(to, 1, root);
 71     }
 72     R1[x] = dfs_clock;
 73 }
 74 
 75 // seg
 76 int M[maxn<<2], tag[maxn<<2];
 77 void gather(int p)
 78 {
 79     M[p] = max(M[p<<1], M[p<<1|1]);
 80 }
 81 void push(int p)
 82 {
 83     if(tag[p])
 84     {
 85         tag[p<<1] += tag[p];
 86         tag[p<<1|1] += tag[p];
 87         M[p<<1] += tag[p];
 88         M[p<<1|1] += tag[p];
 89         tag[p] = 0;
 90     }
 91 }
 92 void build(int p, int l, int r)
 93 {
 94     tag[p] = 0;
 95     if(l < r)
 96     {
 97         int mid = (l + r) >> 1;
 98         build(p<<1, l, mid);
 99         build(p<<1|1, mid + 1, r);
100         gather(p);
101     }
102     else M[p] = w[l];
103 }
104 void modify(int p, int tl, int tr, int l, int r, int v)
105 {
106     if(tl > tr) return;
107     if(tr < l || r < tl) return;
108     if(l <= tl && tr <= r)
109     {
110         tag[p] += v;
111         M[p] += v;
112         return;
113     }
114     push(p);
115     int mid = (tl + tr) >> 1;
116     modify(p<<1, tl, mid, l, r, v);
117     modify(p<<1|1, mid+1, tr, l, r, v);
118     gather(p);
119 }
120 int query(int p, int tl, int tr, int l, int r)
121 {
122     if(tl > tr) return -INF;
123     if(tr < l || r < tl) return -INF;
124     if(l <= tl && tr <= r) return M[p];
125     push(p);
126     int mid = (tl + tr) >> 1;
127     return max(query(p<<1, tl, mid, l, r), query(p<<1|1, mid+1, tr, l, r));
128 }
129 
130 int main(void)
131 {
132     int n, m, q, kase = 0;
133     while(~scanf("%d %d %d", &n, &m, &q))
134     {
135         for(int i = 1; i <= n; i++)
136         {
137             int x;
138             scanf("%d", &x);
139             r[i] = log2(x);
140         }
141         cnt = dfs_clock = 0;
142         for(int i = 1; i <= n; i++) vis[i] = h[i] = 0, fa[i] = i;
143         for(int i = 1; i <= m; i++)
144         {
145             int a, x, y;
146             scanf("%d %d %d", &a, &x, &y);
147             if(a == 1) add(x, y), add(y, x);
148             else Union(x, y);
149         }
150         for(int i = 1; i <= n; i++) vec[Find(i)].push_back(i);
151         for(int i = 1; i <= n; i++)
152             if(!vis[i]) w[dfs_clock + 1] = 0, rl[i] = dfs_clock + 1, dfs(i, 0, i), rr[i] = dfs_clock;
153         build(1, 1, n);
154         printf("Case #%d:\n", ++kase);
155         while(q--)
156         {
157             int a, x, y;
158             scanf("%d %d %d", &a, &x, &y), y = log2(y);
159             if(a == 1)
160             {
161                 if(op[x] % 2) modify(1, 1, n, L2[x], R2[x], r[x] - y);
162                 else modify(1, 1, n, L1[x], R1[x], y - r[x]);
163                 r[x] = y;
164             }
165             else printf("%.3f\n", log(2) * (y + query(1, 1, n, rl[rt[x]], rr[rt[x]]) - query(1, 1, n, L2[x], L2[x])));
166         }
167     }
168     return 0;
169 }
Aguin

 

1008 Hints of sd0061

NthElement 实现上是类似快排 由于只递归一边所以期望on

按询问从大到小做 不同的询问不多 每次排的长度递减 据说就on了

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 unsigned a[10000010];
 8 // Nth_element
 9 int Partition(unsigned a[], int l, int r)
10 {
11     int rd = l + (long long) rand() * 10007 % (r - l + 1);
12     swap(a[rd], a[r]);
13     int j = l - 1;
14     for(int i = l; i < r; i++) if(a[i] <= a[r]) swap(a[++j], a[i]);
15     swap(a[++j], a[r]);
16     return j;
17 }
18 int NthElement(unsigned a[], int l, int r, int id)
19 {
20     if(l == r) return a[l];
21     int m = Partition(a, l, r), cur = m - l + 1;
22     if(id == cur) return a[m];
23     if(id < cur) return NthElement(a, l, m - 1, id);
24     return NthElement(a, m + 1, r, id - cur);
25 }
26 
27 // rand
28 unsigned x, y, z;
29 unsigned rng61() {
30   unsigned t;
31   x ^= x << 16;
32   x ^= x >> 5;
33   x ^= x << 1;
34   t = x;
35   x = y;
36   y = z;
37   z = t ^ x ^ y;
38   return z;
39 }
40 
41 int q[222], p[222], ans[222];
42 bool cmp(int i, int j)
43 {
44     return q[i] > q[j];
45 }
46 
47 int main(void)
48 {
49     unsigned A, B, C;
50     int n, m, kase = 0;
51     while(~scanf("%d %d %u %u %u", &n, &m, &A, &B, &C))
52     {
53         for(int i = 1; i <= m; i++) scanf("%d", q + i), p[i] = i;
54         x = A, y = B, z = C;
55         for(int i = 1; i <= n; i++) a[i] = rng61();
56         sort(p + 1, p + 1 + m, cmp);
57         int mi = n;
58         for(int i = 1; i <= m; i++)
59         {
60             if(i > 1 && q[p[i]] == q[p[i-1]]) ans[p[i]] = ans[p[i-1]];
61             else
62             {
63                 ans[p[i]] = NthElement(a, 1, mi, q[p[i]] + 1);
64                 mi = q[p[i]] + 1;
65             }
66         }
67         printf("Case #%d:", ++kase);
68         for(int i = 1; i <= m; i++) printf(" %u", ans[i]); puts("");
69     }
70     return 0;
71 }
Aguin

 

1009 I Curse Myself

仙人掌环抠出来 k路归并

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <vector>
  4 #include <algorithm>
  5 using namespace std;
  6 typedef long long LL;
  7 typedef pair<int, int> pii;
  8 typedef pair<int, pii> piii;
  9 int k;
 10 
 11 // edge
 12 int cnt, h[1111];
 13 struct edge
 14 {
 15     int to, pre, v;
 16 } e[4444];
 17 void add(int from, int to, int v)
 18 {
 19     cnt++;
 20     e[cnt].pre = h[from];
 21     e[cnt].to = to;
 22     e[cnt].v = v;
 23     h[from] = cnt;
 24 }
 25 
 26 bool cmp(int i, int j)
 27 {
 28     return i > j;
 29 }
 30 
 31 // loop
 32 int vis[1111], fa[1111], fae[1111], num;
 33 vector<int> seq[1111];
 34 void dfs(int x, int f, int eid)
 35 {
 36     vis[x] = 1, fa[x] = f; fae[x] = eid;
 37     for(int i = h[x]; i; i = e[i].pre)
 38     {
 39         int to = e[i].to;
 40         if(to == f || vis[to] == 2) continue;
 41         if(vis[to] == 1)
 42         {
 43             seq[++num].clear();
 44             seq[num].push_back(e[i].v);
 45             int tmp = x;
 46             while(tmp != to)
 47             {
 48                 seq[num].push_back(e[fae[tmp]].v);
 49                 tmp = fa[tmp];
 50             }
 51             sort(seq[num].begin(), seq[num].end(), cmp);
 52         }
 53         else dfs(to, x, i);
 54     }
 55     vis[x] = 2;
 56 }
 57 
 58 vector<int> ret;
 59 
 60 struct PQ
 61 {
 62     piii a[222222];
 63     int tail;
 64     PQ(){tail = 0;}
 65     void push(piii cur)
 66     {
 67         a[++tail] = cur;
 68         int p = tail;
 69         while(p > 1)
 70         {
 71             if(a[p] > a[p/2]) swap(a[p], a[p/2]), p /= 2;
 72             else break;
 73         }
 74     }
 75     piii top()
 76     {
 77         return a[1];
 78     }
 79     void pop()
 80     {
 81         a[1] = a[tail--];
 82         int p = 1;
 83         while(p <= tail)
 84         {
 85             if(p + p <= tail && a[p] < a[p+p] && (p + p + 1 > tail || a[p+p] > a[p+p+1])) swap(a[p], a[p+p]), p *= 2;
 86             else if(p + p + 1 <= tail && a[p] < a[p+p+1]) swap(a[p], a[p+p+1]), p = p + p + 1;
 87             else break;
 88         }
 89     }
 90     bool empty()
 91     {
 92         return tail == 0;
 93     }
 94 } pq;
 95 
 96 void Merge(vector<int> & ans, vector<int> & nxt)
 97 {
 98     int sza = ans.size(), szn = nxt.size();
 99     pq.tail = 0;
100     ret.resize(0);
101     for(int i = 0; i < szn; i++) pq.push(piii(ans[0] + nxt[i], pii(0, i)));
102     while(ret.size() < k && !pq.empty())
103     {
104         piii tmp = pq.top(); pq.pop();
105         ret.push_back(tmp.first);
106         if(tmp.second.first + 1 < sza) pq.push(piii(ans[tmp.second.first+1] + nxt[tmp.second.second], pii(tmp.second.first + 1, tmp.second.second)));
107     }
108     ans = ret;
109 }
110 
111 int main(void)
112 {
113     // freopen("1009.in", "r", stdin);
114     // freopen("ygy.txt", "w", stdout);
115 
116     int n, m, kase = 0;
117     while(~scanf("%d %d", &n, &m))
118     {
119         int sum = cnt = 0;
120         for(int i = 1; i <= n; i++) h[i] = 0, vis[i] = 0;
121         for(int i = 1; i <= m; i++)
122         {
123             int x, y, z;
124             scanf("%d %d %d", &x, &y, &z);
125             sum += z, add(x, y, z), add(y, x, z);
126         }
127         scanf("%d", &k);
128 
129         num = 0, dfs(1, 0, 0);
130         vector<int> ans = seq[1];
131         for(int i = 2; i <= num; i++) Merge(ans, seq[i]);
132 
133         unsigned int ret = 0, sza = ans.size();
134         if(!num) ret += sum;
135         else for(int i = 0; i < sza; i++) ret += (i + 1) * (sum - ans[i]);
136         printf("Case #%d: %u\n", ++kase, ret);
137     }
138     return 0;
139 }
Aguin

 

1010 Journey with Knapsack

1011 KazaQ's Socks

找找规律。

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 typedef long long LL;
 5 
 6 int main(void)
 7 {
 8     int kase = 0;
 9     LL n, k;
10     while(~scanf("%lld %lld", &n, &k))
11     {
12         LL q = (k - 1) / (n - 1), r = (k - 1) % (n - 1) + 1, ans;
13         if(q == 0) ans = r;
14         else if(q % 2) ans = r == 1 ? n : r - 1;
15         else ans = r == 1 ? n - 1 : r - 1;
16         printf("Case #%d: %lld\n", ++kase, ans);
17     }
18     return 0;
19 }
Aguin

 

1012 Limited Permutation

加读入挂直接log就过了

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <vector>
 5 using namespace std;
 6 
 7 // fastIO
 8 namespace fastIO {
 9     #define BUF_SIZE 100000
10     //fread -> read
11     bool IOerror = 0;
12     inline char nc() {
13         static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
14         if(p1 == pend) {
15             p1 = buf;
16             pend = buf + fread(buf, 1, BUF_SIZE, stdin);
17             if(pend == p1) {
18                 IOerror = 1;
19                 return -1;
20             }
21         }
22         return *p1++;
23     }
24     inline bool blank(char ch) {
25         return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
26     }
27     inline void read(int &x) {
28         char ch;
29         while(blank(ch = nc()));
30         if(IOerror)
31             return;
32         for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
33     }
34     #undef BUF_SIZE
35 };
36 using namespace fastIO;
37 
38 typedef long long LL;
39 typedef pair<int, int> pii;
40 const LL mod = 1e9 + 7;
41 const int maxn = 1e6 + 10;
42 int l[maxn], r[maxn];
43 vector<pii> v[maxn];
44 LL inv[maxn], fac[maxn], ifac[maxn];
45 
46 LL C(int a, int b)
47 {
48     return fac[a] * ifac[b] % mod * ifac[a-b] % mod;
49 }
50 
51 LL solve(int L, int R)
52 {
53     if(L > R) return 1LL;
54     pii now = v[L].back(); v[L].pop_back();
55     if(now.first != R) return 0LL;
56     return solve(L, now.second - 1) * solve(now.second + 1, R) % mod * C(R - L, now.second - L) % mod;
57 }
58 
59 int main(void)
60 {
61     fac[0] = ifac[0] = inv[1] = 1;
62     for(int i = 2; i < maxn; i++) inv[i] = (mod - (mod / i) * inv[mod%i] % mod) % mod;
63     for(int i = 1; i < maxn; i++) fac[i] = fac[i-1] * i % mod, ifac[i] = ifac[i-1] * inv[i] % mod;
64     int n, kase = 0;
65     while(read(n), !IOerror)
66     {
67         for(int i = 1; i <= n; i++) read(l[i]), v[i].clear();
68         for(int i = 1; i <= n; i++) read(r[i]), v[l[i]].push_back(pii(r[i], i));
69         for(int i = 1; i <= n; i++) sort(v[i].begin(), v[i].end());
70         LL ans = solve(1, n);
71         printf("Case #%d: %lld\n", ++kase, ans);
72     }
73     return 0;
74 }
Aguin

 

posted @ 2017-07-29 10:41  Aguin  阅读(269)  评论(0编辑  收藏  举报