2018 Multi-University Training Contest 2
Posted aguin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018 Multi-University Training Contest 2相关的知识,希望对你有一定的参考价值。
1001 Absolute
标算卡不过阿???
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 }
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 }
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 }
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 }
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 }
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 }
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 }
以上是关于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