C - Product and GCD
Solved.
题意:
给出$n个数$的乘积,求$这n个数$的最大的可能是GCD
思路:
分解质因子,那么$每个质因子的贡献就是其质因子个数/ n的乘积$
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define ll long long 5 ll n, p; 6 7 int main() 8 { 9 while (scanf("%lld%lld", &n, &p) != EOF) 10 { 11 if (n == 1) 12 { 13 printf("%lld\n", p); 14 continue; 15 } 16 ll res = 1; 17 for (ll i = 2; i * i <= p; ++i) 18 { 19 ll tmp = 0; 20 while (p % i == 0) 21 { 22 ++tmp; 23 p /= i; 24 } 25 while (tmp >= n) 26 { 27 tmp -= n; 28 res *= i; 29 } 30 } 31 printf("%lld\n", res); 32 } 33 return 0; 34 }
D - Harlequin
Solved.
题意:
有$n种颜色的苹果,每种颜色有a_i个,每次可以选择若干个不同颜色的苹果拿掉,轮流拿,谁不能拿谁输$
问 先手胜还是后手胜
思路:
必败局面是当前场上所有颜色的苹果都是偶数个,这样的话,你拿什么,对方跟着你拿,对方肯定胜利
那么必胜局面就是当前场上存在有若干种奇数个颜色的苹果,取掉这些苹果,转换成必败局面留给对方就好了
简单判一判就没了
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int n, x; 5 6 int main() 7 { 8 while (scanf("%d", &n) != EOF) 9 { 10 x = 0; 11 for (int i = 1, y; i <= n; ++i) 12 { 13 scanf("%d", &y); 14 x += y & 1; 15 } 16 puts(x ? "first" : "second"); 17 } 18 return 0; 19 }
E - Negative Doubling
Upsolved.
题意:
给出n个数,对每个数的操作只有 $\cdot -2$ ,求最少多少次操作使得序列变成非下降序列
思路:
我们考虑序列中如果存在正数和负数,那么必然存在一个界限,左边全是负数,右边全是正数
那么我们可以预处理出
$f[i] 表示 使得从i开始是一个非下降序列的最小花费$
$g[i]表示 i以及i以前是一个非下降序列,且全都是负数的最小花费$
维护的过程可以用一个队列
刚开始以为如果当前数比之前的数不满足大小关系,后面的数或者前面的数全都要动
但实际上并不是这样,
比如说
5 3 4 1000000
推到5的时候 只有 3 和 4 要改变
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define ll long long 5 #define N 200010 6 #define pii pair <int, int> 7 int n; 8 ll a[N], b[N], f[N], g[N], lazy; 9 10 void Run() 11 { 12 while (scanf("%d", &n) != EOF) 13 { 14 for (int i = 1; i <= n; ++i) scanf("%lld", a + i); 15 queue <pii> q; 16 f[n] = 0; 17 for (int i = n - 1; i >= 1; --i) 18 { 19 f[i] = f[i + 1]; 20 if (a[i] > a[i + 1]) 21 { 22 ll tmp = a[i + 1]; 23 int cnt = 0; 24 while (tmp < a[i]) 25 { 26 tmp *= 4; 27 cnt += 2; 28 } 29 int x = i; 30 while (!q.empty()) 31 { 32 f[i] += 1ll * (q.front().second - x) * cnt; 33 if (q.front().first <= cnt) cnt -= q.front().first; 34 else 35 { 36 pii tmpp = q.front(); 37 tmpp.first -= cnt; 38 cnt = 0; 39 q.pop(); 40 q.push(tmpp); 41 break; 42 } 43 x = q.front().second; 44 q.pop(); 45 } 46 f[i] += 1ll * (n - x) * cnt; 47 } 48 else 49 { 50 ll tmp = a[i]; 51 int cnt = 0; 52 while (tmp * 4 <= a[i + 1]) 53 { 54 tmp *= 4; 55 cnt += 2; 56 } 57 if (cnt) q.push(pii(cnt, i)); 58 } 59 } 60 while (!q.empty()) q.pop(); 61 g[1] = 1; 62 b[1] = -a[1]; 63 for (int i = 2; i <= n; ++i) 64 { 65 g[i] = g[i - 1] + 1; 66 b[i] = -a[i]; 67 if (b[i] < b[i - 1]) 68 { 69 ll tmp = b[i - 1]; 70 int cnt = 0; 71 while (tmp > b[i]) 72 { 73 tmp *= 4; 74 cnt += 2; 75 } 76 int x = i; 77 while (!q.empty()) 78 { 79 g[i] += 1ll * (x - q.front().second) * cnt; 80 if (q.front().first <= cnt) cnt -= q.front().first; 81 else 82 { 83 pii tmpp = q.front(); 84 q.pop(); 85 tmpp.first -= cnt; 86 cnt = 0; 87 q.push(tmpp); 88 break; 89 } 90 x = q.front().second; 91 q.pop(); 92 } 93 g[i] += 1ll * (x - 1) * cnt; 94 } 95 else 96 { 97 ll tmp = b[i]; 98 int cnt = 0; 99 while (tmp * 4 >= b[i - 1]) 100 { 101 tmp *= 4; 102 cnt += 2; 103 } 104 if (cnt) q.push(pii(cnt, i)); 105 } 106 } 107 ll res = min(f[1], g[n]); 108 for (int i = 1; i < n; ++i) res = min(res, g[i] + f[i + 1]); 109 printf("%lld\n", res); 110 } 111 } 112 113 114 int main() 115 { 116 #ifdef LOCAL 117 freopen("Test.in", "r", stdin); 118 #endif 119 120 Run(); 121 return 0; 122 }