目录
Codeforces Round #558 (Div. 2) 题解
A Eating Soup
分类讨论一下
\(m\) 个断点最多可以将环分成 \(m\) 段,而剩下 \(n-m\) 个点最多可以成为 \(n-m\) 段,取个 \(\min\) 即可
注意 \(m=0\) 时是一个环答案为 \(1\)
// Copyright lzt #include<stdio.h> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> #include<map> #include<set> #include<cmath> #include<iostream> #include<queue> #include<string> #include<ctime> using namespace std; typedef long long ll; typedef std::pair<int, int> pii; typedef long double ld; typedef unsigned long long ull; typedef std::pair<long long, long long> pll; #define fi first #define se second #define pb push_back #define mp make_pair #define rep(i, j, k) for (register int i = (int)(j); i <= (int)(k); i++) #define rrep(i, j, k) for (register int i = (int)(j); i >= (int)(k); i--) #define Debug(...) fprintf(stderr, __VA_ARGS__) inline ll read() { ll x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch <= '9' && ch >= '0') { x = 10 * x + ch - '0'; ch = getchar(); } return x * f; } int n, m; void work() { n = read(), m = read(); if (m == 0) { puts("1"); return; } int num = n - m; printf("%d\n", min(num, m)); } int main() { #ifdef LZT freopen("in", "r", stdin); #endif work(); #ifdef LZT Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC); #endif }
B Cat Party
倒着枚举长度并且维护每一个出现次数的个数
就是维护出现次数为 \(i\) 的数字有多少个
显然出现次数最多只能有两种(因为你只能修改 \(1\) 个数,也就只能修改一个出现次数)
然后就分类讨论一下最后删掉的是哪个即可
// Copyright lzt #include<stdio.h> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> #include<map> #include<set> #include<cmath> #include<iostream> #include<queue> #include<string> #include<ctime> using namespace std; typedef long long ll; typedef std::pair<int, int> pii; typedef long double ld; typedef unsigned long long ull; typedef std::pair<long long, long long> pll; #define fi first #define se second #define pb push_back #define mp make_pair #define rep(i, j, k) for (register int i = (int)(j); i <= (int)(k); i++) #define rrep(i, j, k) for (register int i = (int)(j); i >= (int)(k); i--) #define Debug(...) fprintf(stderr, __VA_ARGS__) inline ll read() { ll x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch <= '9' && ch >= '0') { x = 10 * x + ch - '0'; ch = getchar(); } return x * f; } const int maxn = 100100; int n, cnt; int a[maxn]; int b[maxn], num[maxn]; void work() { n = read(); rep(i, 1, n) a[i] = read(), b[a[i]]++; cnt = 0; set<int> col; rep(i, 1, 100000) { if (b[i]) { num[b[i]]++; cnt++, col.insert(b[i]); } } rrep(i, n, 2) { int nw = *col.begin(); if (num[nw] == 1 && col.size() > 1) nw = *(++col.begin()); if (col.size() <= 2) { bool ok = 0; if (col.size() == 1) { int nw = *col.begin(); if (nw == 1 || num[nw] == 1) ok = 1; else ok = 0; } else { int A = *col.begin(), B = *(++col.begin()); if (num[A] == 1 && A == 1) ok = 1; else if (num[B] == 1 && B == 1) ok = 1; else if (num[B] == 1 && B == A + 1) ok = 1; else ok = 0; } if (ok) { printf("%d\n", i); return; } } num[b[a[i]]]--; if (num[b[a[i]]] == 0) col.erase(b[a[i]]); b[a[i]]--; if (b[a[i]]) { num[b[a[i]]]++; if (num[b[a[i]]] == 1) col.insert(b[a[i]]); } else cnt--; } puts("1"); } int main() { #ifdef LZT freopen("in", "r", stdin); #endif work(); #ifdef LZT Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC); #endif }
C Power Transmission
答案显然是 \(calc(\text{不同的直线数量}) - \sum_{\text{斜率k}} calc(\text{斜率为k的直线数量})\)
其中 \(calc(x)=x*(x-1)/2\)
然后就枚举每两个点形成一条线,然后计数即可
// Copyright lzt #include<stdio.h> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> #include<map> #include<set> #include<cmath> #include<iostream> #include<queue> #include<string> #include<ctime> using namespace std; typedef long long ll; typedef std::pair<int, int> pii; typedef long double ld; typedef unsigned long long ull; typedef std::pair<long long, long long> pll; #define fi first #define se second #define pb push_back #define mp make_pair #define rep(i, j, k) for (register int i = (int)(j); i <= (int)(k); i++) #define rrep(i, j, k) for (register int i = (int)(j); i >= (int)(k); i--) #define Debug(...) fprintf(stderr, __VA_ARGS__) inline ll read() { ll x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch <= '9' && ch >= '0') { x = 10 * x + ch - '0'; ch = getchar(); } return x * f; } const int maxn = 1010; int n; pii p[maxn]; bool sm(double x, double y) { return fabs(x - y) <= 1e-8; } struct Line { // Ax + By + C = 0 double A, B, C; bool operator == (const Line &b) const { return sm(A, b.A) && sm(B, b.B) && sm(C, b.C); } bool operator < (const Line &b) const { if (sm(A, b.A)) { if (sm(B, b.B)) return C < b.C; return B < b.B; } return A < b.A; } void init() { if (A == 0) C = C / B, B = 1; else B = B / A, C = C / A, A = 1; } double calc() { init(); if (A == 1) return B; else return 1e30; } }; map<double, map<double, int> > M; map<double, int> shit; vector<Line> v; void work() { n = read(); rep(i, 1, n) p[i].fi = read(), p[i].se = read(); ll num = 0; rep(i, 1, n) rep(j, i + 1, n) { Line nw; nw.A = p[j].se - p[i].se; nw.B = p[i].fi - p[j].fi; nw.C = 0 - p[i].fi * nw.A - p[i].se * nw.B; nw.init(); double k = nw.calc(); if (M[k][nw.C] == 0) { M[k][nw.C] = 1; num++; shit[k]++; } } num = num * (num - 1) / 2; for (map<double, int>::iterator it = shit.begin(); it != shit.end(); it++) { int nw = it -> se; num = num - nw * 1ll * (nw - 1) / 2; } printf("%lld\n", num); } int main() { #ifdef LZT freopen("in", "r", stdin); #endif work(); #ifdef LZT Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC); #endif }
D Mysterious Code
首先预处理 \(S[i][j]\) 和 \(T[i][j]\) 分别表示当前串的后缀与 \(s/t\) 的前缀的最长公共子串长度为 \(i\) (也就是只有最后 \(i\) 位有用,前面的都忽略),然后下一个位置填了字母 \(j\) 之后那个最长公共子串的长度(类似 \(kmp\) 的 \(fail\))
直接 \(dp\) \(f[i][j][k]\) 表示当前长度为 \(i\),在第一个串上的位置是 \(j\) ,在第二个串上的位置是 \(k\) 的最大 \(f(c',s)-f(c',t)\)
然后转移就暴力枚举一下下一个是啥
// Copyright lzt #include<stdio.h> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> #include<map> #include<set> #include<cmath> #include<iostream> #include<queue> #include<string> #include<ctime> using namespace std; typedef long long ll; typedef std::pair<int, int> pii; typedef long double ld; typedef unsigned long long ull; typedef std::pair<long long, long long> pll; #define fi first #define se second #define pb push_back #define mp make_pair #define rep(i, j, k) for (register int i = (int)(j); i <= (int)(k); i++) #define rrep(i, j, k) for (register int i = (int)(j); i >= (int)(k); i--) #define Debug(...) fprintf(stderr, __VA_ARGS__) inline ll read() { ll x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch <= '9' && ch >= '0') { x = 10 * x + ch - '0'; ch = getchar(); } return x * f; } const int maxn = 1010; int n, m, len; char s[maxn], t[maxn], c[maxn]; int f[maxn][55][55]; int S[55][26], T[55][26]; inline void getmx(int &x, int y) { if (x < y) x = y; } void work() { scanf("%s", c + 1); len = strlen(c + 1); scanf("%s", s + 1); n = strlen(s + 1); rep(i, 0, n) rep(j, 0, 25) { int len = i + 1; rrep(k, min(len, n), 1) { bool flag = true; rep(_, 1, k - 1) if (s[i - k + _ + 1] != s[_]) { flag = false; break; } if (s[k] - 'a' != j) flag = false; if (flag) { S[i][j] = k; break; } } // cout<<i<<' '<<j<<' '<<S[i][j]<<endl; } scanf("%s", t + 1); m = strlen(t + 1); rep(i, 0, m) rep(j, 0, 25) { int len = i + 1; rrep(k, min(len, m), 1) { bool flag = true; rep(_, 1, k - 1) if (t[i - k + _ + 1] != t[_]) { flag = false; break; } if (t[k] - 'a' != j) flag = false; if (flag) { T[i][j] = k; break; } } // cout<<i<<' '<<j<<' '<<T[i][j]<<endl; } rep(i, 0, len) rep(j, 0, n) rep(k, 0, m) f[i][j][k] = -1e9; f[0][0][0] = 0; rep(i, 0, len - 1) rep(j, 0, n) rep(k, 0, m) { if (f[i][j][k] == -1e9) continue; if (c[i + 1] != '*') { int nw = c[i + 1] - 'a', pl = 0; if (S[j][nw] == n) pl++; if (T[k][nw] == m) pl--; getmx(f[i + 1][S[j][nw]][T[k][nw]], f[i][j][k] + pl); } else { rep(nw, 0, 25) { int pl = 0; if (S[j][nw] == n) pl++; if (T[k][nw] == m) pl--; getmx(f[i + 1][S[j][nw]][T[k][nw]], f[i][j][k] + pl); } } } int ans = -1e9; rep(j, 0, n) rep(k, 0, m) { getmx(ans, f[len][j][k]); } printf("%d\n", ans); } int main() { #ifdef LZT freopen("in", "r", stdin); #endif work(); #ifdef LZT Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC); #endif }
E Magical Permutation
// Copyright lzt #include<stdio.h> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> #include<map> #include<set> #include<cmath> #include<iostream> #include<queue> #include<string> #include<ctime> using namespace std; typedef long long ll; typedef std::pair<int, int> pii; typedef long double ld; typedef unsigned long long ull; typedef std::pair<long long, long long> pll; #define fi first #define se second #define pb push_back #define mp make_pair #define rep(i, j, k) for (register int i = (int)(j); i <= (int)(k); i++) #define rrep(i, j, k) for (register int i = (int)(j); i >= (int)(k); i--) #define Debug(...) fprintf(stderr, __VA_ARGS__) inline ll read() { ll x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch <= '9' && ch >= '0') { x = 10 * x + ch - '0'; ch = getchar(); } return x * f; } const int maxn = 200200; int n, ans, pos; int a[maxn], lb[20]; vector<int> vec; bool vis[maxn << 2]; void add(int v) { int tmp = v; rrep(i, 20, 0) { if (v & (1 << i)) { if (lb[i]) v ^= lb[i]; else { vec.pb(tmp); lb[i] = v; break; } } } } void dfs(int v, int num) { printf("%d ", v); vis[v] = 1; if (num == (1 << ans)) return; rep(i, 0, vec.size() - 1) if (!vis[v ^ vec[i]]) { dfs(v ^ vec[i], num + 1); break; } } void work() { n = read(); rep(i, 1, n) a[i] = read(); sort(a + 1, a + n + 1); ans = 0, pos = 1; rep(i, 1, 20) { while (pos <= n && a[pos] < (1 << i)) { add(a[pos]); pos++; } bool flag = true; rep(j, 0, i - 1) if (!lb[j]) flag = false; if (flag) ans = i; } memset(lb, 0, sizeof(lb)); vec.clear(); rep(i, 1, n) { if (a[i] < (1 << ans)) add(a[i]); } printf("%d\n", ans); dfs(0, 1); } int main() { #ifdef LZT freopen("in", "r", stdin); #endif work(); #ifdef LZT Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC); #endif }
来源:https://www.cnblogs.com/wawawa8/p/10842606.html