2016ACM/ICPC亚洲区沈阳站 Solution
Posted dup4
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2016ACM/ICPC亚洲区沈阳站 Solution相关的知识,希望对你有一定的参考价值。
A - Thickest Burger
水。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int t; 5 int a, b; 6 7 int main() 8 { 9 scanf("%d" ,&t); 10 while (t--) 11 { 12 scanf("%d%d", &a, &b); 13 if (a > b) swap(a, b); 14 printf("%d ", a + b * 2); 15 } 16 return 0; 17 }
B - Relative atomic mass
水。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int t; 5 char s[100]; 6 7 int main() 8 { 9 scanf("%d", &t); 10 while (t--) 11 { 12 scanf("%s", s); 13 int res = 0; 14 for (int i = 0, len = strlen(s); i < len; ++i) 15 { 16 if (s[i] == ‘H‘) res += 1; 17 if (s[i] == ‘C‘) res += 12; 18 if (s[i] == ‘O‘) res += 16; 19 } 20 printf("%d ", res); 21 } 22 return 0; 23 }
C - Recursive sequence
题意:求$F[n] = F[n - 1] + 2 cdot F[n - 2] + n^4$
思路:考虑
$n^4 = (n - 1)^4 + 4 cdot (n - 1) ^ 3 + 6 cdot (n - 1) ^2 + 4 cdot (n - 1) ^ 2 + (n - 1) + 1$
然后进行递推即可
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define ll long long 5 6 const ll MOD = 2147493647; 7 8 int t; 9 ll n, a, b; 10 11 struct node 12 { 13 ll a[7][7]; 14 node () { memset(a, 0, sizeof a); } 15 node operator * (const node &r) const 16 { 17 node ans = node(); 18 for (int i = 0; i < 7; ++i) for (int j = 0; j < 7; ++j) for (int k = 0; k < 7; ++k) 19 ans.a[i][j] = (ans.a[i][j] + a[i][k] * r.a[k][j] % MOD) % MOD; 20 return ans; 21 } 22 }; 23 24 ll tmp[7][7] = 25 { 26 1, 1, 0, 0, 0, 0, 0, 27 2, 0, 0, 0, 0, 0, 0, 28 1, 0, 1, 0, 0, 0, 0, 29 4, 0, 4, 1, 0, 0, 0, 30 6, 0, 6, 3, 1, 0, 0, 31 4, 0, 4, 3, 2, 1, 0, 32 1, 0, 1, 1, 1, 1, 1, 33 }; 34 35 ll tmp2[7] = 36 { 37 0, 0, 16, 8, 4, 2, 1, 38 }; 39 40 node qmod(ll n) 41 { 42 node base = node(); 43 for (int i = 0; i < 7; ++i) for (int j = 0; j < 7; ++j) 44 base.a[i][j] = tmp[i][j]; 45 node res = node(); 46 for (int i = 0; i < 7; ++i) res.a[0][i] = tmp2[i]; 47 while (n) 48 { 49 if (n & 1) res = res * base; 50 base = base * base; 51 n >>= 1; 52 } 53 return res; 54 } 55 56 int main() 57 { 58 scanf("%d", &t); 59 while (t--) 60 { 61 scanf("%lld%lld%lld", &n, &a, &b); 62 if (n == 1) printf("%lld ", a); 63 else if (n == 2) printf("%lld ", b); 64 else 65 { 66 tmp2[0] = b; tmp2[1] = a; 67 printf("%lld ", qmod(n - 2).a[0][0]); 68 } 69 } 70 return 0; 71 }
D - Winning an Auction
留坑。
E - Counting Cliques
题意:给出n个点,m条边,求点集大小为S的完全图个数
思路:以每个点为起点搜有多少完全图
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 1e2 + 10; 6 7 int n, m, s; 8 int ans; 9 int arr[maxn], tot; 10 int mp[maxn][maxn]; 11 vector<int>G[maxn]; 12 13 void Init(int N) 14 { 15 ans = 0; 16 for(int i = 1; i <= N; ++i) 17 { 18 G[i].clear(); 19 mp[i][i] = 1; 20 for(int j = i + 1; j <= N; ++j) 21 { 22 mp[i][j] = mp[j][i] = 0; 23 } 24 } 25 } 26 27 void DFS(int u, int cnt) 28 { 29 if(cnt == s) 30 { 31 ++ans; 32 return ; 33 } 34 for(auto it: G[u]) 35 { 36 bool flag = true; 37 for(int i = 0; i < tot; ++i) 38 { 39 if(!mp[arr[i]][it]) 40 { 41 flag = false; 42 break; 43 } 44 } 45 if(flag) 46 { 47 arr[tot++] = it; 48 DFS(it, cnt + 1); 49 tot--; 50 } 51 } 52 } 53 54 int main() 55 { 56 int t; 57 scanf("%d", &t); 58 while(t--) 59 { 60 scanf("%d %d %d", &n, &m, &s); 61 Init(n); 62 for(int i = 1; i <= m; ++i) 63 { 64 int u, v; 65 scanf("%d %d", &u, &v); 66 G[u].push_back(v); 67 mp[u][v] = mp[v][u] = 1; 68 } 69 for(int i = 1; i <= n; ++i) 70 { 71 tot = 0; 72 arr[tot++] = i; 73 DFS(i, 1); 74 } 75 printf("%d ", ans); 76 } 77 return 0; 78 }
G - Do not pour out
题意:
思路:
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 const double eps = 1e-20; 6 const double PI = acos(-1.0); 7 8 int sgn(double x) 9 { 10 if(fabs(x) < eps) return 0; 11 else return x > 0 ? 1 : -1; 12 } 13 14 double d; 15 16 double calc(double arc) 17 { 18 return PI * cos(arc) - arc * cos(arc) + sin(arc) - sin(arc) * sin(arc) * sin(arc) / 3.0; 19 } 20 21 int check(double mid) 22 { 23 double tmp = (calc(acos(2.0 * tan(mid) - 1.0)) - calc(PI)) / tan(mid); 24 return sgn(tmp - d * PI); 25 } 26 27 double get(double l, double r) 28 { 29 if(check(l) == 0) return l; 30 int cnt = 256; 31 while(cnt--) 32 { 33 double mid = (l + r) / 2.0; 34 int tmp = check(mid); 35 if(tmp == 0) return mid; 36 if(tmp == 1) r = mid; 37 if(tmp == -1) l = mid; 38 } 39 return l; 40 } 41 42 int main() 43 { 44 int t; 45 scanf("%d", &t); 46 while(t--) 47 { 48 scanf("%lf", &d); 49 if(sgn(d) == 0) 50 { 51 printf("0.00000 "); 52 } 53 else if(sgn(d - 1) > 0) 54 { 55 double arc = atan(2.0 - d); 56 double ans = PI / cos(arc); 57 printf("%.5f ", ans); 58 } 59 else 60 { 61 double tmp = get(eps, PI / 4.0); 62 double t1 = 2.0 * tan(tmp) - 1.0; 63 double arc = acos(t1); 64 double ans = PI - arc + cos(arc) * sin(arc); 65 ans = ans / sin(tmp); 66 printf("%.5f ", ans); 67 } 68 } 69 return 0; 70 }
H - Guessing the Dice Roll
留坑。
I - The Elder
题意:给出一棵树,每个点到根节点1的方式可以是连续走,也可以经过一个点消耗时间p,使得重新计算所经过路径,求每个点到根节点最小的最大时间 时间为$L^2$
思路:考虑朴素的转移 $F[i] = min(F[j] + p + (sum[i] - sum[j]) ^ 2) (j 为 i 的祖先们)$
拆分式子
$F[i] = F[j] + p + {sum[i]} ^ 2 - 2 cdot sum[i] cdot sum[j] + {sum[j]} ^ 2$
$F[j] = F[i] + 2 cdot sum[i] cdot sum[j] - p - {sum[i]} ^ 2 - {sum[j]} ^ 2$
考虑斜率优化
树上的单调队列优化可以通过标记最后一个更改的值,然后还原(XHT)
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 typedef long long ll; 6 7 const int maxn = 1e5 + 10; 8 9 struct Edge{ 10 int to, nxt; 11 ll w; 12 Edge(){} 13 Edge(int to, int nxt, ll w): to(to), nxt(nxt), w(w){} 14 }edge[maxn << 1]; 15 16 ll ans; 17 ll dis[maxn]; 18 ll dp[maxn]; 19 int n, p; 20 int que[maxn]; 21 int head[maxn], tot; 22 23 void Init(int N) 24 { 25 for(int i = 1; i <= N; ++i) head[i] = -1; 26 tot = ans = 0; 27 } 28 29 void addedge(int u, int v, ll w) 30 { 31 edge[tot] = Edge(v, head[u], w); 32 head[u] = tot++; 33 } 34 35 ll dy(int j, int k) 36 { 37 return dp[j] - dp[k] + dis[j] * dis[j] - dis[k] * dis[k]; 38 } 39 40 ll dx(int j, int k) 41 { 42 return 2 * (dis[j] - dis[k]); 43 } 44 45 void DFS(int u, int fa, int l, int r) 46 { 47 int remind = -1; 48 49 if(u != 1) 50 { 51 while(l < r && dy(que[l + 1], que[l]) <= dis[u] * dx(que[l + 1], que[l])) l++; 52 // cout << u << " " << que[l] << " " << dp[que[l]] + p + (dis[u] - dis[que[l]]) * (dis[u] - dis[que[l]]) << endl; 53 dp[u] = min(dis[u] * dis[u], dp[que[l]] + p + (dis[u] - dis[que[l]]) * (dis[u] - dis[que[l]])); 54 while(l < r && dy(que[r], que[r - 1]) * dx(u, que[r]) >= dy(u, que[r]) * dx(que[r], que[r - 1])) r--; 55 remind = que[++r]; 56 que[r] = u; 57 } 58 59 ans = max(ans, dp[u]); 60 61 for(int i = head[u]; ~i; i = edge[i].nxt) 62 { 63 int v = edge[i].to; 64 if(v == fa) continue; 65 dis[v] = dis[u] + edge[i].w; 66 DFS(v, u, l, r); 67 } 68 69 if(remind != -1) que[r] = remind; 70 } 71 72 73 int main() 74 { 75 int t; 76 scanf("%d", &t); 77 while(t--) 78 { 79 scanf("%d %d", &n, &p); 80 Init(n); 81 for(int i = 1; i < n; ++i) 82 { 83 int u, v, w; 84 scanf("%d %d %d", &u, &v ,&w); 85 addedge(u, v, w); 86 addedge(v, u, w); 87 } 88 DFS(1, -1, 1, 0); 89 // for(int i = 1; i <= n; ++i) cout << i << " " << dp[i] << endl; 90 printf("%lld ", ans); 91 } 92 return 0; 93 }
J - Query on a graph
留坑。
K - New Signal Decomposition
留坑。
L - A Random Turn Connection Game
留坑。
M - Subsequence
留坑。
以上是关于2016ACM/ICPC亚洲区沈阳站 Solution的主要内容,如果未能解决你的问题,请参考以下文章
HDU 5950 Recursive sequence 递推+矩阵快速幂 (2016ACM/ICPC亚洲区沈阳站)
HDU 5950 - Recursive sequence - [矩阵快速幂加速递推][2016ACM/ICPC亚洲区沈阳站 Problem C]