E (尺取法)
#include <bits/stdc++.h> #define ll long long using namespace std; const int maxn = 2e5 + 5; int n; char s[maxn]; int main() { cin >> s + 1 >> n; int len = strlen(s + 1); for (int i = 1; i <= len; ++i) s[i + len] = s[i]; ll ans = 0; for (int i = 1, x = 0, j = 0; i <= len; ++i) { while (!x && j + 1 <= (len << 1)) if (s[++j] == 'E') ++x; if (x) ans += max(0, n - j + i); if (s[i] == 'E') --x; } cout << ans; return 0; }
G(后缀自动机)
#include <bits/stdc++.h> using namespace std; const int maxn = 4e5 + 10; struct node { int fa, len; map<char, int> nxt; }tr[maxn]; int sz, las; void init() { sz = las = 1; tr[1].len = tr[1].fa = 0; map<char, int>().swap(tr[1].nxt); } void add(char c) { int p = las; int cur = las = ++sz; tr[cur].len = tr[p].len + 1; for (; p && !tr[p].nxt.count(c); p = tr[p].fa) tr[p].nxt[c] = cur; if (p == 0) { tr[cur].fa = 1; return; } int q = tr[p].nxt[c]; if (tr[q].len == tr[p].len + 1) { tr[cur].fa = q; return; } int nq = ++sz; tr[nq] = tr[q]; tr[nq].len = tr[p].len + 1; for (; p && tr[p].nxt[c] == q; p = tr[p].fa) tr[p].nxt[c] = nq; tr[q].fa = tr[cur].fa = nq; } int dp[maxn], n; char s[maxn >> 1]; void solve() { int lenx = 1, p = 1, tmp = 0; for(int& i = lenx; s[i]; ++i) { if (tr[p].nxt.count(s[i])) p = tr[p].nxt[s[i]], ++tmp; else { while (!tr[p].nxt.count(s[i]) && p) p = tr[p].fa; if(p == 0) p = 1, tmp = 0; else tmp = tr[p].len + 1, p = tr[p].nxt[s[i]]; } if(!tmp) { puts("-1"); return; } dp[i] = dp[i - tmp] + 1; }--lenx; printf("%d ", dp[lenx]); } int main() { scanf("%s%d", s + 1, &n); init(); for (int i = 1; s[i]; ++i) add(s[i]); for (int i = 1; i <= n; ++i) scanf("%s", s + 1), solve(); return 0; }
I(记忆化搜索)
#include <bits/stdc++.h> #define ll long long using namespace std; int n, m, a[1005][2005]; int v[2005], mod = 1e9 + 7; ll ans2, ans[1005]; ll work(int k) { if (v[k]) { return ans[k];} v[k] = 1; for (int i = 1; i <= a[k][0]; ++i) { if (a[k][i] <= m) ans[k] = (ans[k] + work(a[k][i])) % mod; else { if (!v[a[k][i]]) ++ans2, v[a[k][i]] = 1; ans[k] = (ans[k] + 1) % mod; } } return ans[k]; } int main() { cin >> n >> m; for (int i = 1; i <= m; ++i) { cin >> a[i][0]; for (int j = 1; j <= a[i][0]; ++j) cin >> a[i][j]; } work(1); cout << ans[1] << ' ' << ans2; return 0; }
K(给定方程的零点公式,拆括号号,复杂度够,直接暴力拆)
#include <bits/stdc++.h> #define ll long long using namespace std; const int maxn = 1e4 + 5; char s[maxn]; int tot; ll a[maxn], b[maxn]; int main() { cin >> s + 1; b[0] = 1; for (int i = 2; s[i]; ++i) if (s[i] != s[i - 1]) a[++tot] -= (i - 1 << 1) + 1; for (int i = 1; i <= tot; ++i) { b[i] = b[i - 1]; for (int j = i - 1; j; --j) b[j] = b[j - 1] + b[j] * a[i]; b[0] *= a[i]; } int flag = 1; if (s[1] == 'H' && tot & 1) flag = -1; else if (s[1] == 'A' && tot % 2 == 0) flag = -1; printf("%d %lld", tot, flag * b[tot]); for (int i = tot - 1; i >= 0; --i) printf(" %lld", flag * b[i]); return 0; }
L
#include <bits/stdc++.h> #define ll long long #define P pair<int, int> using namespace std; int n, m, a, b[1005][1005], ans; inline int read() { char c = getchar(); while (c != 'G' && c != 'B') c = getchar(); return c == 'G'; } void init() { for (int i = 1; i <= n; ++i) { a = read(); b[i][1] = 1; for (int j = 2, c; j <= m; ++j, a = c) { c = read(); if (a == c) b[i][j] = b[i][j - 1] + 1; else b[i][j] = 1; } } } void work(stack<P> &st, int k, int j) { int w = 1; for (P p = st.top(); b[k][j] < b[p.second][j]; st.pop(), p = st.top()) { int c = min(p.first + k - p.second - 1, b[p.second][j]); ans = max(ans, c * c); w += p.first; } st.push({ w, k }); } int main() { cin >> n >> m; init(); for (int i = m; i; --i) { stack<P> st; st.push({0, 0}); for (int j = 1; j <= n + 1; ++j) work(st, j, i); } cout << ans; return 0; }
M(签到题)
#include <bits/stdc++.h> using namespace std; const int maxn = 1005; int n, a[maxn], x, d[maxn], mx; int main() { cin >> n >> x; for (int i = 1; i <= n; ++i) cin >> a[i]; for (int i = 1; i <= n; ++i) { d[i] = 1; int ls = a[i]; for (int j = i + 1; j <= n; ++j) if (a[j] - ls <= x) ls = a[j], ++d[i]; mx = max(mx, d[i]); } cout << mx; return 0; }