2都结束了我才补完1的题
我真的太菜了
总体来说不是很难(反正我也AK不了)
公式挺好推的,容斥随便搞搞就出来了,但是我错了8次....刚开始以为是取模的问题,后来把所有的数都取模了还是有问题,才发现因为用同余定理时候存在减法,会产生有负数的情况,所以需要(ans+MOD) % MOD,就这个简单的问题坑了我将近一个小时
#include <cstdio> using namespace std; const long long MOD = 1e9 + 7; int main() { long long n, m; scanf("%lld %lld", &n, &m); n--; m--; long long ans = 0; n = n % MOD; m = m % MOD; ans = ((((((n - 1) % MOD * ((n + 1) % MOD)) % MOD) * (m % MOD)) % MOD) * 2) % MOD; ans = ans % MOD + (((((m + 1) % MOD * ((m - 1) % MOD)) % MOD) * (n % MOD)) % MOD * 2) % MOD; ans = ans % MOD + ((((((n + 1) % MOD * ((m - 1) % MOD)) % MOD) * (n % MOD)) % MOD) * 2) % MOD; ans = ans % MOD + ((((((n - 1) % MOD * ((m + 1) % MOD)) % MOD) * (m % MOD)) % MOD) * 2) % MOD; ans = ans % MOD - (((((n - 1) % MOD * (m % MOD)) % MOD) * 4) % MOD + ((((m - 1) % MOD * (n % MOD)) % MOD) * 4) % MOD) % MOD; ans = (ans + MOD) % MOD; printf("%lld", ans); return 0; }
B.kotori和bangdream
大水题
#include <cstdio> using namespace std; int main() { int n, x, a, b; scanf("%d %d %d %d", &n, &x, &a, &b); double ans = (1.0 * x / 100) * a + (1 - 1.0 * x / 100) * b; ans *= n; printf("%.2lf", ans); return 0; }
B.umi和弓道
简单的计算几何,注意细节就行了,不过场上看到是计算几何直接吓跑了
扫描二维码关注公众号,回复:
8990517 查看本文章
#include <cstdio> #include <algorithm> using namespace std; typedef long long ll; const int N = 100010; long double posy[N], posx[N]; int main() { ll x0, y0; scanf("%lld %lld", &x0, &y0); int n, k, cx = 0, cy = 0; scanf("%d %d", &n, &k); for (int i = 0; i < n; i++) { ll x, y; scanf("%lld %lld", &x, &y); if (x * x0 > 0 && y * y0 > 0) continue; if (x * x0 < 0) { long double k = 1.0 * (y0 - y) / (x0 - x); posy[cy++] = y0 - k * x0; } if (y * y0 < 0) { if (x0 == x) posx[cx++] = x0; else { long double k = 1.0 * (y0 - y) / (x0 - x); posx[cx++] = x0 - y0 * 1.0 / k; } } } sort(posx, posx + cx); sort(posy, posy + cy); long double ans = 5 * 1e9; for (int i = n - k - 1; i < cx; i++) ans = min(ans, posx[i] - posx[i - (n - k - 1)]); for (int i = n - k - 1; i < cy; i++) ans = min(ans, posy[i] - posy[i - (n - k - 1)]); if (ans == 5 * 1e9) puts("-1"); else printf("%Lf", ans); return 0; } // y - y0 = k * (x - x0) // -y0/k = x - x0
D.hanayo和米饭
大水题*2(虽然我没加llWA了一发)
#include <cstdio> using namespace std; int main() { long long n; scanf("%lld", &n); long long tot = (1 + n) * n / 2; for (int i = 0; i < n - 1; i++) { long long a; scanf("%lld", &a); tot -= a; } printf("%lld", tot); return 0; }
E.rin和快速迭代
刚开始超时了,还以为是太暴力了,结果测了大数据发现是因为int暴了,因为(int i = 0; i * i < n; i++)的时候,i * i还是一个int,就爆炸了,这个问题挺常见的,结果我还是没吸取教训QAQ
#include <cstdio> using namespace std; typedef long long ll; int main() { ll n, ans = 0; scanf("%lld", &n); while (n != 2) { ll tot = 0; for (ll i = 1; i * i <= n; i++) if (n % i == 0) { if (i * i == n) tot++; else tot += 2; } n = tot; ans++; } printf("%lld", ans); return 0; }
F.maki和tree
赛后补的题,不同于标答的dfs,我就直接并查集合并,结果刚开始把黑色也合并了...错的很惨,后来改了发现超时,改成了路径压缩就过了
#include <cstdio> #include <algorithm> #include <vector> using namespace std; const int N = 100010; vector < int > e[N]; int fa[N]; int bl[N], cnt = 0; long long tot[N]; int cl[N]; int find(int a) { return (fa[a] == a) ? fa[a] : (fa[a] = find(fa[a])); } int main() { int n; scanf("%d", &n); getchar(); for (int i = 1; i <= n; i++) { char c = getchar(); if (c == 'W') cl[i] = 0; else { cl[i] = 1; bl[cnt++] = i; } } for (int i = 1; i <= n; i++) fa[i] = i, tot[i] = 1; for (int i = 0; i < n - 1; i++) { int a, b; scanf("%d %d", &a, &b); int f = find(a); int fb = find(b); if (f != fb && cl[a] == cl[b] && cl[a] == 0) { fa[fb] = f; tot[f] += tot[fb]; } else if (f != fb && cl[a] != cl[b]) { e[f].push_back(fb); e[fb].push_back(f); } } long long ans = 0; for (int k = 0; k < cnt; k++) { int i = bl[k]; tot[i] = 0; long long res = 0; for (int j = 0; j < e[i].size(); j++) { int q = find(e[i][j]); tot[i] += tot[q]; } for (int j = 0; j < e[i].size(); j++) { int q = find(e[i][j]); res = res + (tot[i] - tot[q]) * tot[q]; } res = res / 2; ans = ans + res + tot[i]; } printf("%lld", ans); return 0; } //
G.eli和字符串
尺取法水题
#include <cstdio> #include <algorithm> using namespace std; const int N = 200010; char s[N]; int main() { int n, k; scanf("%d %d", &n, &k); scanf("%s", s); int ans = 0x3f3f3f3f; for (int i = 0; i < 26; i++) { int l = 0, r = 0, tot = 0; while (r < n) { if (tot < k) { while (s[r] != i + 'a' && r < n) //注意这里的判断,不要越界了 r++; if (s[r] == i + 'a') // 注意判断是哪种情况 tot++, r++; else break; } if (tot == k) { while (s[l] != i + 'a' && l <= r) l++; ans = min(ans, (r - l)); tot--; l++; } } } if (ans == 0x3f3f3f3f) puts("-1"); else printf("%d", ans); return 0; }
H.nozomi和字符串
尺取法水题*2
#include <cstdio> #include <algorithm> using namespace std; const int N = 200010; char s[N]; int main() { int n, k; scanf("%d %d", &n, &k); scanf("%s", s); int kk = k; int l = 0, r = 0, ans = 0; while (r < n) { if (k > 0){ while (s[r] == '0' && r < n) r++; ans = max(ans, r - l); if (s[r] == '1') k--, r++; else break; } if (k == 0) { while (s[r] == '0' && r < n) r++; ans = max(ans, r - l); while (s[l] == '0' && l <= r) l++; l++; k++; } } l = 0, r = 0; k = kk; while (r < n) { if (k > 0){ while (s[r] == '1' && r < n) r++; ans = max(ans, r - l); if (s[r] == '0') k--, r++; else break; } if (k == 0) { while (s[r] == '1' && r < n) r++; ans = max(ans, r - l); while (s[l] == '1' && l <= r) l++; l++; k++; } } printf("%d", ans); return 0; }
I.nico和niconiconi
线性dp,暴力一点就行了
#include <cstdio> #include <algorithm> using namespace std; const int N = 3000010; char s[N]; char s1[10] = "nico"; char s2[10] = "niconi"; char s3[11] = "niconiconi"; long long dp[N]; int main() { int n, a, b, c; scanf("%d %d %d %d", &n, &a, &b, &c); scanf("%s", s); for (int i = 3; i < n; i++) { dp[i + 1] = dp[i]; for (int j = 0; j < 4; j++) { if (s[i - j] != s1[3 - j]) break; if (j == 3) dp[i + 1] = max(dp[i + 1], dp[i - 4 + 1] + a); } if (i >= 5) for (int j = 0; j < 6; j++) { if (s[i - j] != s2[5 - j]) break; if (j == 5) dp[i + 1] = max(dp[i + 1], dp[i - 6 + 1] + b); } if (i >= 9) for (int j = 0; j < 10; j++) { if (s[i - j] != s3[9 - j]) break; if (j == 9) dp[i + 1] = max(dp[i + 1], dp[i - 10 + 1] + c); } } printf("%lld", dp[n]); return 0; }
J .u's的影响力
场上最难的题?斐波那契数列可以矩阵快速幂求,麻烦在取模上,幂太大了怎么办,反正我场上没想出办法,赛后看了题解发现可以用费马小定理%(mod - 1)解决,看了一个证明,看的有点懵(反正我也不负责数学)不过过段时间还是再看一遍吧,然后就是有很多坑
#include <cstdio> using namespace std; typedef long long ll; const ll MOD = 1e9 + 7; struct Matrix{ ll m[3][3]; }; inline void assign(Matrix* a) { for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) a->m[i][j] = 0; } inline Matrix multi(Matrix a, Matrix b) { Matrix c; assign(&c); //初始化 for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) for (int k = 0; k < 2; k++) c.m[i][j] = ((a.m[i][k] * b.m[k][j] % (MOD - 1)) + c.m[i][j]) % (MOD - 1); return c; } ll pow1(ll n) { n--; Matrix res, a; assign(&res); assign(&a); //初始化 res.m[0][0] = 1; res.m[1][1] = 1; a.m[0][0] = 1; a.m[0][1] = 1; a.m[1][0] = 1; while (n) { if (n & 1) res = multi(a, res); a = multi(a, a); n >>= 1; } return res.m[0][0]; } ll pow2(ll a, ll b) { if (a % MOD == 0) return 0; //快速幂一定要注意这个啊 ll res = 1; a = a % MOD; while (b) { if (b & 1) res = res * a % MOD; a = a * a % MOD; b >>= 1; } return res % MOD; } int main() { ll n, x, y, a, b; scanf("%lld %lld %lld %lld %lld", &n, &x, &y, &a, &b); if (n == 1) { printf("%lld", x % MOD); return 0; } if (n == 2) { printf("%lld", y % MOD); return 0; } x %= MOD; y %= MOD; ll a1 = pow1(n - 2); ll b1 = pow1(n - 1); //printf("%lld %lld\n", a1, b1); ll ans = pow2(x % MOD, a1) * pow2(y % MOD, b1) % MOD * pow2(a % MOD, (a1 + b1 - 1) * (b % (MOD - 1)) % (MOD - 1)) % MOD; // 取模真的要多来几次,不然就会爆炸 printf("%lld", ans % MOD); return 0; } // f(1) = x, f(2) = y, f(3) = x * y * a^b, f(4) = x * y^2 * a^2b, f(5) = x^2 * y^3 * a^4b // f(6) = x^3 * y^5 * a^7b f(7) = x^5 * y^8 * a^12b f(8) = x^8 * y^13 * a^20b