#include<iostream> #include<cstdio> #define int long long
usingnamespace std;
constint N = 3e6 + 10; int f[N]; int n; int sum;
signedmain(){ scanf("%lld", &n); for (int i = 0; i < n; ++i) { scanf("%lld", &f[i]); sum = f[n - 1]; } for (int i = 0; i < n; ++i) { f[i] = 2 * f[i] - sum; } sum = f[n - 1]; for (int len = 2; len <= n; len <<= 1) { int p = len / 2; for (int l = 0; l < n; l += len) { for (int k = l; k <= l + p - 1; ++k) { int tmp = f[k]; f[k] = (f[k] + f[k + p]) / 2; f[k + p] = (-tmp + f[k + p]) / 2; } } } for (int i = 0; i < n; ++i) { printf("%lld ", f[i]); } return0; }
structNode { int link, ch[27], len, siz, minn; }tr[4 * N]; char s[N]; int n; int tot; int las; int ans; int len;
voidadd(int c, int i){ int p = las, np = ++tot; las = np; tr[np].len = tr[p].len + 1; tr[np].minn = i; while (p && !tr[p].ch[c]) tr[p].ch[c] = np, p = tr[p].link; if (!p) tr[np].link = 1; else { int v = tr[p].ch[c]; if (tr[v].len == tr[p].len + 1) tr[np].link = v; else { int nv = ++tot; tr[nv] = tr[v]; tr[nv].len = tr[p].len + 1; while (p && tr[p].ch[c] == v) tr[p].ch[c] = nv, p = tr[p].link; tr[np].link = tr[v].link = nv; } } }
voidquery(int i){ len = 0; ans = 0; int u = 1; for (int j = i; j <= n; ++j) { if (!tr[u].ch[s[j] - 'a' + 1] || tr[tr[u].ch[s[j] - 'a' + 1]].minn >= j) break; ++len; u = tr[u].ch[s[j] - 'a' + 1]; ans = tr[u].minn - len + 1; } }
intmain(){ scanf("%s", s + 1); n = strlen(s + 1); las = tot = 1; for (int i = 1; i <= n; ++i) { add(s[i] - 'a' + 1, i); } for (int i = 1; i <= n;) { ans = 0; query(i); if (!ans) { printf("-1 %d ", s[i]); ++i; } else { printf("%d %d ", len, ans - 1); i = i + len; } } return0; }
总结
在 SAM 上,一个点被拆成两个点,拆成的两个点的 endpos 最小值等于原来点的 endpos 最小值.
#include<iostream> #include<cstdio> #include<vector> #define int long long
usingnamespace std;
constint N = 3e6 + 20; constint mod = 1e9 + 7; int inv[N], fac[N], ifac[N]; int n, m, k; int pos[N], s[N]; int ans1, ans; int f[N]; int vis[N], t; int cho[N]; int kno[N], sc[N]; vector<int> has[N]; vector<int> lim;
intC(int n, int m){ if (n < 0) return0; if (n < m) return0; return fac[n] * ifac[m] % mod * ifac[n - m] % mod; }
intsolve(){ for (int i = 1; i <= t; ++i) { if (cho[i]) { s[pos[kno[i]]] -= sc[i] + 1; } } int res = ans1; for (auto i : lim) { res = res * C(s[i] + has[i].size() - 1, has[i].size() - 1) % mod; } for (int i = 1; i <= t; ++i) { if (cho[i]) { s[pos[kno[i]]] += sc[i] + 1; } } return res; }