2018 Multi-University Training Contest 2

Posted aguin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018 Multi-University Training Contest 2相关的知识,希望对你有一定的参考价值。

1001 Absolute

1002 Counting Permutations

标算卡不过阿???

技术分享图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 int mod, g[222], h[222][777], inv_fac[777], C[222][222], po[777][222];
 5 
 6 int a[777], b[777], c[777], d[777];
 7 int solve(int n, int x) {
 8     if(x > g[n]) return 0;
 9     for(int i = 0; i <= g[n]; ++i) a[i] = 0, b[i] = 0;
10     b[0] = 1;
11     for(int i = 0; i <= g[n]; ++i) {
12         for(int j = i + 1; j > 0; --j) b[j] = b[j - 1];
13         b[0] = 0;
14         for(int j = 0; j <= i; ++j) b[j] = (b[j] + (LL) (mod - i) * b[j + 1]) % mod;
15     }
16     for(int i = 0; i <= g[n]; ++i) {
17         for(int j = g[n]; j >= 0; --j) c[j] = 0;
18         for(int j = 0; j <= g[n] + 1; ++j) d[j] = b[j];
19         for(int j = g[n]; j >= 0; --j) {
20             c[j] = d[j + 1];
21             d[j] = (d[j] + (LL) i * c[j]) % mod;
22         }
23         assert(d[0] == 0);
24         int y = (LL) inv_fac[i] * inv_fac[g[n] - i] % mod * h[n][i] % mod;
25         if((g[n] - i) % 2) y = mod - y;
26         for(int j = 0; j <= g[n]; ++j) a[j] = (a[j] + (LL) y * c[j]) % mod;
27     }
28     return a[x];
29 }
30 
31 int main() {
32     for(int i = 1; i <= 200; ++i)
33         for(int j = 1; j <= i; ++j)
34             g[i] = max(g[i], g[j - 1] + g[i - j] + min(j, i - j + 1));
35     scanf("%d", &mod);
36     inv_fac[0] = inv_fac[1] = 1;
37     for(int i = 2; i <= g[200]; ++i) inv_fac[i] = (LL) (mod - mod / i) * inv_fac[mod % i] % mod;
38     for(int i = 3; i <= g[200]; ++i) inv_fac[i] = (LL) inv_fac[i] * inv_fac[i - 1] % mod;
39     for(int i = 0; i <= 200; ++i) C[i][0] = C[i][i] = 1;
40     for(int i = 2; i <= 200; ++i)
41         for(int j = 1; j < i; ++j)
42             C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % mod;
43     for(int i = 1; i <= g[200]; ++i) {
44         po[i][0] = 1;
45         for(int j = 1; j <= 200; ++j) po[i][j] = (LL) po[i][j - 1] * i % mod;
46     }
47     for(int i = 0; i <= g[200]; ++i) h[0][i] = 1;
48     for(int i = 1; i <= 200; ++i)
49         for(int j = 1; j <= g[200]; ++j)
50             for(int k = 1; k <= i; ++k)
51                 h[i][j] = (h[i][j] + (LL) po[j][min(k, i - k + 1)] * h[k - 1][j] % mod * h[i - k][j] % mod * C[i - 1][k - 1]) % mod;
52     int n, x;
53     while(~scanf("%d %d", &n, &x)) printf("%d
", solve(n, x));
54     return 0;
55 }
Aguin

UPD:看了下dls的暴力真香发现对称的部分可以只枚举一半终于卡过了

技术分享图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 int mod, g[222], h[222][777], inv_fac[777], C[222][222], po[777][222];
 5 
 6 int a[777], b[777], c[777], d[777];
 7 int solve(int n, int x) {
 8     if(x > g[n]) return 0;
 9     for(int i = 0; i <= g[n]; ++i) a[i] = 0, b[i] = 0;
10     b[0] = 1;
11     for(int i = 0; i <= g[n]; ++i) {
12         for(int j = i + 1; j > 0; --j) b[j] = b[j - 1];
13         b[0] = 0;
14         for(int j = 0; j <= i; ++j) b[j] = (b[j] + (LL) (mod - i) * b[j + 1]) % mod;
15     }
16     for(int i = 0; i <= g[n]; ++i) {
17         for(int j = g[n]; j >= 0; --j) c[j] = 0;
18         for(int j = 0; j <= g[n] + 1; ++j) d[j] = b[j];
19         for(int j = g[n]; j >= 0; --j) {
20             c[j] = d[j + 1];
21             d[j] = (d[j] + (LL) i * c[j]) % mod;
22         }
23         assert(d[0] == 0);
24         int y = (LL) inv_fac[i] * inv_fac[g[n] - i] % mod * h[n][i] % mod;
25         if((g[n] - i) % 2) y = mod - y;
26         for(int j = 0; j <= g[n]; ++j) a[j] = (a[j] + (LL) y * c[j]) % mod;
27     }
28     return a[x];
29 }
30 
31 int main() {
32     for(int i = 1; i <= 200; ++i)
33         for(int j = 1; j <= i; ++j)
34             g[i] = max(g[i], g[j - 1] + g[i - j] + min(j, i - j + 1));
35     scanf("%d", &mod);
36     inv_fac[0] = inv_fac[1] = 1;
37     for(int i = 2; i <= g[200]; ++i) inv_fac[i] = (LL) (mod - mod / i) * inv_fac[mod % i] % mod;
38     for(int i = 3; i <= g[200]; ++i) inv_fac[i] = (LL) inv_fac[i] * inv_fac[i - 1] % mod;
39     for(int i = 0; i <= 200; ++i) C[i][0] = C[i][i] = 1;
40     for(int i = 2; i <= 200; ++i)
41         for(int j = 1; j < i; ++j)
42             C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % mod;
43     for(int i = 1; i <= g[200]; ++i) {
44         po[i][0] = 1;
45         for(int j = 1; j <= 200; ++j) po[i][j] = (LL) po[i][j - 1] * i % mod;
46     }
47     for(int i = 0; i <= g[200]; ++i) h[0][i] = 1;
48     for(int i = 1; i <= 200; ++i) {
49         for(int j = 1; j <= g[200]; ++j) {
50             for(int k = 1; k <= i; ++k) {
51                 int l = k - 1, r = i - k, c = 1;
52                 if(l > r) break;
53                 if(l != r) c++;
54                 h[i][j] = (h[i][j] + (LL) c * po[j][min(k, i - k + 1)] * h[k - 1][j] % mod * h[i - k][j] % mod * C[i - 1][k - 1]) % mod;
55             }
56         }
57     }
58     int n, x;
59     while(~scanf("%d %d", &n, &x)) printf("%d
", solve(n, x));
60     return 0;
61 }
Aguin

 

1003 Cover

被教了一下午欧拉回路最后忘记判孤立点了……

技术分享图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 4e5 + 10;
 4 int u[maxn], v[maxn], vis[maxn];
 5 vector<int> G[maxn];
 6 vector< vector<int> > ans;
 7 vector<int> tmp, node, o;
 8 
 9 void dfs1(int x) {
10     vis[x] = 1;
11     if(G[x].size() % 2 == 1) node.push_back(x);
12     for(int i = 0; i < G[x].size(); ++i) {
13         int eid = G[x][i], to = eid > 0 ? v[eid] : u[-eid];
14         if(vis[to]) continue;
15         dfs1(to);
16     }
17 }
18 
19 int e_vis[maxn];
20 void dfs(int x) {
21     while(!G[x].empty()) {
22         int eid = G[x][G[x].size() - 1];
23         while(e_vis[abs(eid)]) {
24             G[x].pop_back();
25             if(G[x].empty()) return;
26             eid = G[x][G[x].size() - 1];
27         }
28         int U = u[abs(eid)], V = v[abs(eid)];
29         int nxt = eid > 0 ? V : U;
30         e_vis[abs(eid)] = 1;
31         dfs(nxt);
32         tmp.push_back(eid);
33     }
34 }
35 
36 int main() {
37     int n, m;
38     while(~scanf("%d %d", &n, &m)) {
39         for(int i = 1; i <= n; ++i) G[i].clear(), vis[i] = 0;
40         for(int i = 1; i <= m; ++i) {
41             e_vis[i] = 0;
42             scanf("%d %d", u + i, v + i);
43             G[u[i]].push_back(i);
44             G[v[i]].push_back(-i);
45         }
46         int add = 0;
47         ans.clear();
48         for(int i = 1; i <= n; ++i) {
49             if(vis[i]) continue;
50             node.clear(), dfs1(i);
51             for(int j = 0; j < node.size(); j += 2) {
52                 int eid = m + (++add);
53                 e_vis[eid] = 0;
54                 u[eid] = node[j], v[eid] = node[j+1];
55                 G[node[j]].push_back(eid);
56                 G[node[j+1]].push_back(-eid);
57             }
58             tmp.clear(), dfs(i);
59             if(tmp.empty()) continue;
60             if(node.empty()) ans.push_back(tmp);
61             else {
62                 int st = 0;
63                 while(abs(tmp[st]) <= m) st++;
64                 st++;
65                 for(int j = 0; j < tmp.size(); ++j) {
66                     o.clear();
67                     int k = j;
68                     while(abs(tmp[(st + k) % tmp.size()]) <= m) k++;
69                     for(int p = j; p < k; ++p) o.push_back(tmp[(p+st) % tmp.size()]);
70                     ans.push_back(o);
71                     j = k;
72                 }
73             }
74         }
75         printf("%d
", int(ans.size()));
76         for(int i = 0; i < ans.size(); ++i) {
77             printf("%d", (int) ans[i].size());
78             reverse(ans[i].begin(), ans[i].end());
79             for(int j = 0; j < ans[i].size(); ++j)
80                 printf(" %d", ans[i][j]);
81             puts("");
82         }
83     }
84     return 0;
85 }
Aguin

 

1004 Game

取1换先后手

技术分享图片
1 #include <bits/stdc++.h>
2 using namespace std;
3 
4 int main() {
5     int n;
6     while(~scanf("%d", &n)) puts("Yes");
7     return 0;
8 }
Aguin

 

1005 Hack It

不会构造

技术分享图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 bool a[2304][2304];
 4 int main(){
 5     for(int i=1;i<=47;i++){
 6         for(int j=1;j<=47;j++){
 7             a[i][(i-1)*47+j]=true;
 8         }
 9     }
10     for(int i=0;i<=46;i++){
11         for(int j=1;j<=47;j++){
12             for(int k=0;k<=46;k++){
13                 a[(i+1)*47+j][k*47+(j+k*i-1)%47+1]=true;
14             }
15         }
16     }
17     puts("2000");
18     for(int i=1;i<=2000;i++)
19         {
20         for(int j=1;j<=2000;j++)
21             if (a[i][j]) putchar(1); else putchar(0);
22         puts("");
23     }
24     return 0;
25 }
不知道谁写的?

 

1006 Matrix

打容斥系数表

技术分享图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int mod = 998244353;
 4 int po[9000005], C[3005][3005], fa[3005], fb[3005];
 5 typedef long long LL;
 6 
 7 int main() {
 8     po[0] = 1;
 9     for(int i = 1; i < 9000005; ++i) po[i] = (po[i-1] + po[i-1]) % mod;
10     for(int i = 0; i < 3005; ++i) C[i][0] = C[i][i] = 1;
11     for(int i = 2; i < 3005; ++i)
12         for(int j = 1; j < i; ++j)
13             C[i][j] = (C[i-1][j] + C[i-1][j-1]) % mod;
14     int n, m, A, B;
15     while(~scanf("%d %d %d %d", &n, &m, &A, &B)) {
16         for(int i = A; i <= n; ++i) {
17             fa[i] = 1;
18             for(int j = A; j < i; ++j) fa[i] = (fa[i] + mod - (LL) C[i][j] * fa[j] % mod) % mod;
19         }
20         for(int i = B; i <= m; ++i) {
21             fb[i] = 1;
22             for(int j = B; j < i; ++j) fb[i] = (fb[i] + mod - (LL) C[i][j] * fb[j] % mod) % mod;
23         }
24         int ans = 0;
25         for(int i = A; i <= n; ++i)
26             for(int j = B; j <= m; ++j)
27                 ans = (ans + (LL) fa[i] * C[n][i] % mod * fb[j] % mod * C[m][j] % mod * po[(n-i)*(m-j)]) % mod;
28         printf("%d
", ans);
29     }
30     return 0;
31 }
Aguin

 

1007 Naive Operations

只在整数部分增加的时候递归子树仔细一想是两个log的

技术分享图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1e5 + 10;
 4 int b[maxn];
 5 
 6 int sum[maxn<<2], mi[maxn<<2], tag[maxn<<2];
 7 void gather(int p) {
 8     sum[p] = sum[p << 1] + sum[p << 1 | 1];
 9     mi[p] = min(mi[p << 1], mi[p << 1 | 1]);
10 }
11 void push(int p) {
12     if (tag[p]) {
13         tag[p << 1] += tag[p];
14         tag[p << 1 | 1] += tag[p];
15         mi[p << 1] -= tag[p];
16         mi[p << 1 | 1] -= tag[p];
17         tag[p] = 0;
18     }
19 }
20 void build(int p, int l, int r) {
21     tag[p] = sum[p] = 0;
22     if (l < r) {
23         int mid = (l + r) >> 1;
24         build(p << 1, l, mid);
25         build(p << 1 | 1, mid + 1, r);
26         gather(p);
27     } else mi[p] = b[l];
28 }
29 void modify(int p, int tl, int tr, int l, int r) {
30     if (tl > tr) return;
31     if (tr < l || r < tl) return;
32     if (l <= tl && tr <= r) {
33         if(tl == tr) {
34             mi[p]--, tag[p] = 0;
35             while(mi[p] <= 0) mi[p] += b[tl], sum[p]++;
36             return;
37         }
38         else if(mi[p] > 1) {tag[p]++, mi[p]--; return;}
39     }
40     push(p);
41     int mid = (tl + tr) >> 1;
42     modify(p << 1, tl, mid, l, r);
43     modify(p << 1 | 1, mid + 1, tr, l, r);
44     gather(p);
45 }
46 int query(int p, int tl, int tr, int l, int r) {
47     if (tl > tr) return 0;
48     if (tr < l || r < tl) return 0;
49     if (l <= tl && tr <= r) return sum[p];
50     push(p);
51     int mid = (tl + tr) >> 1;
52     return query(p << 1, tl, mid, l, r) + query(p << 1 | 1, mid + 1, tr, l, r);
53 }
54 
55 int main() {
56     int n, q;
57     while(~scanf("%d %d", &n, &q)) {
58         for(int i = 1; i <= n; ++i) scanf("%d", b + i);
59         build(1, 1, n);
60         while(q--) {
61             int l, r;
62             char s[11];
63             scanf("%s %d %d", s, &l, &r);
64             if(s[0] == a) modify(1, 1, n, l, r);
65             else printf("%d
", query(1, 1, n, l, r));
66         }
67     }
68     return 0;
69 }
Aguin

 

1008 Odd Shops

1009 Segment

1010 Swaps and Inversions

沙雕逆序对

技术分享图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn = 1e5 + 10;
 5 int a[maxn];
 6 
 7 // BIT
 8 int c[maxn];
 9 int lowbit(int s) {
10     return s & (-s);
11 }
12 void modify(int i, int x, int n) {
13     while (i <= n) c[i] += x, i += lowbit(i);
14     return;
15 }
16 int query(int i) {
17     int ret = 0;
18     while (i > 0) ret += c[i], i -= lowbit(i);
19     return ret;
20 }
21 
22 vector<int> b;
23 int main() {
24     int n, x, y;
25     while(~scanf("%d %d %d", &n, &x, &y)) {
26         b.clear();
27         for(int i = 1; i <= n; ++i) scanf("%d", a + i), b.push_back(a[i]);
28         sort(b.begin(), b.end());
29         unique(unique(b.begin(), b.end()), b.end());
30         for(int i = 1; i <= n; ++i) a[i] = lower_bound(b.begin(), b.end(), a[i]) - b.begin() + 1;
31         for(int i = 1; i <= n; ++i) c[i] = 0;
32         LL ans = 0;
33         for(int i = 1; i <= n; ++i) {
34             ans += query(n) - query(a[i]);
35             modify(a[i], 1, n);
36         }
37         printf("%lld
", min(x, y) * ans);
38     }
39     return 0;
40 }
Aguin

 

以上是关于2018 Multi-University Training Contest 2的主要内容,如果未能解决你的问题,请参考以下文章

2018 Multi-University Training Contest 2

2018 Multi-University Training Contest 9

2018 Multi-University Training Contest 4

2018 Multi-University Training Contest 4

2018 Multi-University Training Contest 3

2018 Multi-University Training Contest 8