@ljt12138
2018-11-17T03:13:11.000000Z
字数 24722
阅读 995
这是一些luogu/loj/bzoj模板题的代码...
注意更新pre...
#include <bits/stdc++.h>using namespace std;const int MAXN = 10005;int n, m, blk;struct node {int l, r, id, ans;friend bool operator < (const node &a, const node &b){if (a.l/blk == b.l/blk && a.r/blk == b.r/blk) return a.id < b.id;if (a.l/blk == b.l/blk) return a.r < b.r;return a.l < b.l;}} qy[MAXN];int qtop = 0;inline bool cmp(const node &a, const node &b){ return a.id < b.id; }int a[MAXN];int T[MAXN*100];int pos[MAXN], dt[MAXN], id[MAXN], pre[MAXN], mtop = 0, top = 0;int main(){scanf("%d%d", &n, &m);for (int i = 1; i <= n; i++)scanf("%d", &a[i]);blk = pow(n, 2.0/3.0);for (int i = 1; i <= m; i++) {char c;int aa, b;scanf("\n%c %d%d", &c, &aa, &b);if (c == 'Q') qy[++qtop] = (node){aa, b, i, 0};else pos[++mtop] = aa, pre[mtop] = a[aa], dt[mtop] = b, id[mtop] = i;}sort(qy+1, qy+qtop+1);int L = 1, R = 0, Ans = 0;memset(T, 0, sizeof T);for (int i = 1; i <= qtop; i++) {while (R < qy[i].r) R++, T[a[R]]++, Ans += (T[a[R]] == 1);while (L > qy[i].l) L--, T[a[L]]++, Ans += (T[a[L]] == 1);while (L < qy[i].l) T[a[L]]--, Ans -= (T[a[L]] == 0), L++;while (R > qy[i].r) T[a[R]]--, Ans -= (T[a[R]] == 0), R--;while (top+1 <= mtop && id[top+1] <= qy[i].id) {top++;if (a[pos[top]] != dt[top]) {pre[top] = a[pos[top]];if (pos[top] >= L && pos[top] <= R) {T[a[pos[top]]]--, T[dt[top]]++;Ans -= (T[a[pos[top]]] == 0), Ans += (T[dt[top]] == 1);}a[pos[top]] = dt[top];}}while (id[top] > qy[i].id) {if (a[pos[top]] != pre[top]) {if (pos[top] >= L && pos[top] <= R) {T[a[pos[top]]]--, T[pre[top]]++;Ans -= (T[a[pos[top]]] == 0), Ans += (T[pre[top]] == 1);}a[pos[top]] = pre[top];}top--;}qy[i].ans = Ans;}sort(qy+1, qy+qtop+1, cmp);for (int i = 1; i <= qtop; i++)printf("%d\n", qy[i].ans);return 0;}
#include <bits/stdc++.h>using namespace std;const int MAXN = 200005;const int mod = 998244353, g = 3;int A[MAXN], B[MAXN], C[MAXN];int n, m;int rev[MAXN];int power(int a, int n){int ans = 1;for (int i = 0; i <= 30; i++) {if (n&(1<<i)) ans = (long long)ans*a%mod;a = (long long)a*a%mod;}return ans;}inline int inv(int n){ return power(n, mod-2); }void NTT(int A[], int n, int flag){int lgn = int(log2(n)+0.1);rev[0] = 0;for (int i = 1; i < n; i++) rev[i] = (rev[i>>1]>>1)|((i&1)<<(lgn-1));for (int i = 0; i < n; i++)if (rev[i] < i)swap(A[i], A[rev[i]]);for (int k = 2; k <= n; k <<= 1) {int dw = power(g, (mod-1)/k);if (flag == -1) dw = inv(dw);for (int i = 0; i < n; i += k) {int w = 1, u, t;for (int j = 0; j < k>>1; j++) {u = A[i+j], t = (long long)w*A[i+j+(k>>1)]%mod;A[i+j] = (u+t)%mod, A[i+j+(k>>1)] = ((u-t)%mod+mod)%mod;w = (long long)w*dw%mod;}}}if (flag == -1) {int invn = inv(n);for (int i = 0; i < n; i++)A[i] = (long long)A[i]*invn%mod;}}char str[MAXN];int main(){scanf("%d", &n);scanf("%s", str);for (int i = 0; i < n; i++) A[i] = str[n-i-1]-'0';scanf("%s", str);for (int i = 0; i < n; i++) B[i] = str[n-i-1]-'0';int m = 1;while (m < n*2) m <<= 1;NTT(A, m, 1), NTT(B, m, 1);for (int i = 0; i < m; i++) C[i] = (long long)A[i]*B[i]%mod;NTT(C, m, -1);for (int i = 0; i < m-1; i++) {C[i+1] += C[i]/10;C[i] %= 10;}int k = m-1;while (C[k] == 0) k--;for (int i = k; i >= 0; i--)printf("%d", C[i]);puts("");return 0;}
#include <bits/stdc++.h>using namespace std;const int MAXN = 20005;struct node {int to, next, dis;} edge[MAXN*2];int head[MAXN], top = 0;inline void push(int i, int j, int d){ edge[++top] = (node) {j, head[i], d}, head[i] = top; }int vis[MAXN], siz[MAXN];int num[3];long long ans = 0;int n;void dfs_siz(int nd, int f){siz[nd] = 1;for (int i = head[nd]; i; i = edge[i].next) {int to = edge[i].to;if (to == f || vis[to]) continue;dfs_siz(to, nd), siz[nd] += siz[to];}}void find_center(int nd, int f, const int tot_siz, int &cnt, int &ans){int maxs = tot_siz-siz[nd];for (int i = head[nd]; i; i = edge[i].next) {int to = edge[i].to;if (to == f || vis[to]) continue;find_center(to, nd, tot_siz, cnt, ans);maxs = max(maxs, siz[to]);}if (maxs < cnt) cnt = maxs, ans = nd;}void dfs_calc(int nd, int f, int dt){ans += num[(3-dt)%3]*2;for (int i = head[nd]; i; i = edge[i].next) {int to = edge[i].to;if (to == f || vis[to]) continue;dfs_calc(to, nd, (dt+edge[i].dis)%3);}}void dfs_paint(int nd, int f, int dt){num[dt]++;for (int i = head[nd]; i; i = edge[i].next) {int to = edge[i].to;if (to == f || vis[to]) continue;dfs_paint(to, nd, (dt+edge[i].dis)%3);}}void calc(int nd){dfs_siz(nd, 0);int cnt = INT_MAX, center = 0;find_center(nd, 0, siz[nd], cnt, center);vis[center] = 1, ans++, num[0]++;for (int i = head[center]; i; i = edge[i].next) {int to = edge[i].to, d = edge[i].dis;if (vis[to]) continue;dfs_calc(to, center, d%3);dfs_paint(to, center, d%3);}num[0] = num[1] = num[2] = 0;for (int i = head[center]; i; i = edge[i].next) {int to = edge[i].to;if (!vis[to]) calc(to);}}inline long long gcd(long long a, long long b){ return b == 0 ? a : gcd(b, a%b); }int main(){scanf("%d", &n);for (int i = 1; i < n; i++) {int u, v, d;scanf("%d%d%d", &u, &v, &d);push(u, v, d), push(v, u, d);}calc(1);long long tot = (long long)n*n;long long c = gcd(ans, tot);cout << ans/c << "/" << tot/c << endl;return 0;}
#include <bits/stdc++.h>using namespace std;const int MAXN = 500005;struct node {int to, next;} edge[MAXN*2];int head[MAXN], top = 0;inline void push(int i, int j){ edge[++top] = (node) {j, head[i]}, head[i] = top; }int n, m, S, u, v;vector<pair<int,int> > vec[MAXN];int fa[MAXN], vis[MAXN], ans[MAXN];inline int findf(int nd){ return fa[nd]?fa[nd]=findf(fa[nd]):nd; }void tarjan(int nd, int f){vis[nd] = 1;for (int i = 0; i < vec[nd].size(); i++) {int to = vec[nd][i].first, id = vec[nd][i].second;if (vis[to]) ans[id] = findf(to);}for (int i = head[nd]; i; i = edge[i].next) {int to = edge[i].to;if (to == f) continue;tarjan(to, nd);}fa[nd] = f;}int main(){scanf("%d%d%d", &n, &m, &S);for (int i = 1; i < n; i++) {scanf("%d%d", &u, &v);push(u, v), push(v, u);}for (int i = 1; i <= m; i++) {scanf("%d%d", &u, &v);vec[u].push_back(make_pair(v, i)), vec[v].push_back(make_pair(u, i));}tarjan(S, 0);for (int i = 1; i <= m; i++)printf("%d\n", ans[i]);return 0;}
#include <bits/stdc++.h>using namespace std;const int MAXN = 100005;struct node {pair<int, int> dat;int lc, rc;node(){ lc = rc = 0; }} hp[MAXN];int merge(int a, int b){if (a == 0 || b == 0) return a+b;if (hp[a].dat > hp[b].dat) swap(a, b);hp[a].lc = merge(hp[a].lc, b);swap(hp[a].lc, hp[a].rc);return a;}pair<int,int> pop(int &a){pair<int, int> ans = hp[a].dat;a = merge(hp[a].lc, hp[a].rc);return ans;}int del[MAXN], fa[MAXN], tree[MAXN];inline int findf(int nd){ return fa[nd]?fa[nd]=findf(fa[nd]):nd; }int n, m, u;int main(){scanf("%d%d", &n, &m);for (int i = 1; i <= n; i++) {scanf("%d", &u);hp[i].dat = make_pair(u, i);tree[i] = i;}int opt, x, y;for (int i = 1; i <= m; i++) {scanf("%d", &opt);if (opt == 1) {scanf("%d%d", &x, &y);if (del[x] || del[y] || findf(x) == findf(y)) continue;x = findf(x), y = findf(y);fa[x] = y, tree[y] = merge(tree[x], tree[y]);} else {scanf("%d", &x);if (del[x]) puts("-1");else {x = findf(x);pair<int, int> ans = pop(tree[x]);del[ans.second] = 1;printf("%d\n", ans.first);}}}return 0;}
#include <bits/stdc++.h>using namespace std;const int MAXN = 300005;int chl[MAXN][2], fa[MAXN], dat[MAXN], sum[MAXN], rev[MAXN];int stk[MAXN], top;inline bool is_rt(int x){ return chl[fa[x]][0] != x && chl[fa[x]][1] != x; }inline void pdw(int nd){if (chl[nd][0]) rev[chl[nd][0]] ^= rev[nd];if (chl[nd][1]) rev[chl[nd][1]] ^= rev[nd];if (rev[nd]) swap(chl[nd][0], chl[nd][1]), rev[nd] = 0;}inline void update(int nd){ sum[nd] = dat[nd]^sum[chl[nd][0]]^sum[chl[nd][1]]; }void zig(int nd){int p = fa[nd], g = fa[p], tp = chl[p][0] != nd, tg = chl[g][0] != p;int son = chl[nd][tp^1];if (son) fa[son] = p;if (!is_rt(p)) chl[g][tg] = nd;fa[p] = nd, fa[nd] = g, chl[nd][tp^1] = p, chl[p][tp] = son;update(p), update(nd);}void splay(int nd){stk[top = 1] = nd;for (int i = nd; !is_rt(i); i = fa[i]) stk[++top] = fa[i];while (top) pdw(stk[top--]);while (!is_rt(nd)) {int p = fa[nd], g = fa[p], tp = chl[p][0] != nd, tg = chl[g][0] != p;if (is_rt(p)) { zig(nd); break; }else if (tp == tg) zig(p), zig(nd);else zig(nd), zig(nd);}}void access(int x){for (int y = 0; x; x = fa[y = x])splay(x), chl[x][1] = y, update(x);}void make_rt(int x){access(x), splay(x), rev[x] ^= 1;}inline void link(int x, int y){ make_rt(x), fa[x] = y, access(x); }inline void cut(int x, int y){make_rt(x), access(y), splay(y);if (chl[y][0] != x) return;chl[y][0] = fa[x] = 0;update(y);}int findf(int x){access(x), splay(x);while (chl[x][0]) x = chl[x][0];return x;}int query(int x, int y){make_rt(x), access(y), splay(y);return sum[chl[y][0]]^dat[y];}void modify(int x, int y){access(x), splay(x), dat[x] = y, update(x);}int n, m;inline int read(){int a = 0, c;do c = getchar(); while (!isdigit(c));while (isdigit(c)) {a = a*10+c-'0';c = getchar();}return a;}int main(){n = read(), m = read();for (int i = 1; i <= n; i++)dat[i] = read();int opt, x, y;for (int i = 1; i <= m; i++) {opt = read(), x = read(), y = read();if (opt == 0) {printf("%d\n", query(x, y));} else if (opt == 1) {int a = findf(x), b = findf(y);if (a == b) continue;link(x, y);} else if (opt == 2) {cut(x, y);} else {modify(x, y);}}return 0;}
#include <bits/stdc++.h>using namespace std;const int MAXN = 100005;struct node {int to, next;} edge[MAXN*2];int head[MAXN], top = 0;inline void push(int i, int j){ edge[++top] = (node) {j, head[i]}, head[i] = top; }int dfn[MAXN], low[MAXN], dfn_top = 0;int cur[MAXN];int n, m;void tarjan(int nd, int f){// cerr << f << "-->" << nd << endl;dfn[nd] = ++dfn_top, low[nd] = dfn[nd];int cnt = 0;for (int i = head[nd]; i; i = edge[i].next) {int to = edge[i].to;if (to == f) continue;if (dfn[to]) low[nd] = min(low[nd], dfn[to]);else {cnt++, tarjan(to, nd), low[nd] = min(low[nd], low[to]);if (f && low[to] >= dfn[nd]) cur[nd] = 1;}}if (!f && cnt >= 2) cur[nd] = 1;}int main(){scanf("%d%d", &n, &m);for (int i = 1; i <= m; i++) {int u, v;scanf("%d%d", &u, &v);push(u, v), push(v, u);}for (int i = 1; i <= n; i++)if (!dfn[i])tarjan(i, 0);int cnt = 0;for (int i = 1; i <= n; i++)if (cur[i])cnt++;printf("%d\n", cnt);for (int i = 1; i <= n; i++)if (cur[i])printf("%d ", i);puts("");return 0;}
#include <bits/stdc++.h>using namespace std;const int MAXN = 20005;int chl[MAXN][26], fail[MAXN], top = 0, root = 0;int vis[MAXN];struct node {int to, next;} edge[MAXN*2];int head[MAXN], top_tp = 0;inline void push(int i, int j){ edge[++top_tp] = (node) {j, head[i]}, head[i] = top_tp; }int pos[MAXN];inline void push(int &nd, const char *str, int id){if (!nd) nd = ++top;if (*str != '\0') push(chl[nd][*str-'a'], str+1, id);else pos[id] = nd;}queue<int> que;void build(){int nd = root; que.push(nd);while (!que.empty()) {int nd = que.front(); que.pop();for (int i = 0; i < 26; i++) {if (!chl[nd][i]) continue;int p = fail[nd];while (p && !chl[p][i]) p = fail[p];if (!p) fail[chl[nd][i]] = root;else fail[chl[nd][i]] = chl[p][i];que.push(chl[nd][i]);}}for (int i = 2; i <= top; i++) push(fail[i], i);}void match(char *str){int nd = root;for (char *p = str; *p != '\0'; ++p) {while (nd && !chl[nd][*p-'a']) nd = fail[nd];if (!nd) nd = root;else { nd = chl[nd][*p-'a'], vis[nd]++; }}}void display(int nd, int tab, char from){if (!nd) return;for (int i = 1; i <= tab; i++) putchar(' ');printf("--%c--> %d, fail = %d, vis = %d\n", from, nd, fail[nd], vis[nd]);for (int i = 0; i < 26; i++) {if (chl[nd][i]) display(chl[nd][i], tab+2, i+'a');}}void dfs1(int nd){for (int i = head[nd]; i; i = edge[i].next) {int to = edge[i].to;dfs1(to), vis[nd] += vis[to];}}char str[151][75];int n;char s[1000005];int main(){while (scanf("%d", &n)) {if (n == 0) break;root = top = top_tp = 0;memset(head, 0, sizeof head), memset(chl, 0, sizeof chl), memset(fail, 0, sizeof fail);memset(vis, 0, sizeof vis);for (int i = 1; i <= n; i++) scanf("%s", str[i]), push(root, str[i], i);scanf("%s", s);build();match(s);dfs1(root);int max_val = 0;for (int i = 1; i <= n; i++) {max_val = max(max_val, vis[pos[i]]);}printf("%d\n", max_val);for (int i = 1; i <= n; i++)if (vis[pos[i]] == max_val)puts(str[i]);}return 0;}
#include <bits/stdc++.h>using namespace std;const int MAXN = 1005;int n, m, e, u, v;inline int read(){int a = 0, c;do c = getchar(); while (!isdigit(c));while (isdigit(c)) {a = a*10+c-'0';c = getchar();}return a;}struct node {int to, next;} edge[MAXN*MAXN];int head[MAXN], top = 0;inline void push(int i, int j){ edge[++top] = (node) {j, head[i]}, head[i] = top; }int link[MAXN], vis[MAXN];int s[MAXN];bool arg(int nd){for (int i = head[nd]; i; i = edge[i].next) {int to = edge[i].to;if (vis[to]) continue;vis[to] = 1;if (!link[to] || arg(link[to])) {link[to] = nd;s[nd] = 1;return 1;}}return 0;}void match(){int cnt = 0;for (int i = 1; i <= n; i++) {memset(vis, 0, sizeof vis);if (!s[i] && arg(i)) cnt++;}printf("%d\n", cnt);}int main(){n = read(), m = read(), e = read();for (int i = 1; i <= e; i++) {u = read(), v = read();if (u > n || v > m) continue;push(u, v);}match();return 0;}
#include <bits/stdc++.h>using namespace std;const int MAXN = 105;double A[MAXN][MAXN];int n;void solve(){for (int i = 1; i <= n; i++) {int pos = i;while (pos <= n && A[pos][i] == 0) pos++;if (pos > n) {puts("No Solution");return;}swap(A[pos], A[i]);for (int j = 1; j <= n; j++) {if (j == i) continue;double tmp = -A[j][i]/A[i][i];for (int k = 1; k <= n+1; k++)A[j][k] += A[i][k]*tmp;}}for (int i = 1; i <= n; i++)printf("%.2f\n", A[i][n+1]/A[i][i]);}int main(){scanf("%d", &n);for (int i = 1; i <= n; i++)for (int j = 1; j <= n+1; j++)scanf("%lf", &A[i][j]);solve();return 0;}
和拉格朗日插值法类似,就是构造一个方程满足所有方程组。考虑。设为满足的数,,则可以构造:
#include <bits/stdc++.h>using namespace std;const int mod = 999911659;const int a[] = {2, 3, 4679, 35617}, M = mod-1;int power(int a, int b, int mod){int ans = 1;for (int i = 0; i <= 30; i++) {if ((b>>i)&1) ans = (long long)ans*a%mod;a = (long long)a*a%mod;}return ans;}inline int gcd(int a, int b){ return b==0?a:gcd(b, a%b); }int ext_gcd(int a, int b, int &x, int &y){if (b == 0) {x = 1, y = 0;return a;}int ans = ext_gcd(b, a%b, y, x);y = y-a/b*x;return ans;}int inv(int a, int m) // (a, b) = 1{int x, y;ext_gcd(a, m, x, y);return (x%m+m)%m;}int fac[4][40005], ifac[4][40005];inline int choose(int n, int m, int mod_id){if (n < m) return 0;return (long long)fac[mod_id][n]*ifac[mod_id][m]%a[mod_id]*ifac[mod_id][n-m]%a[mod_id];}inline int lucas(int n, int m, int mod_id){if (n < a[mod_id]) return choose(n, m, mod_id);return (long long)lucas(n/a[mod_id], m/a[mod_id], mod_id)*choose(n%a[mod_id], m%a[mod_id], mod_id)%a[mod_id];}inline int choose_mod(int n, int m){int ans[4], x = 0;// cerr << n << " " << m << endl;for (int i = 0; i < 4; i++) {ans[i] = lucas(n, m, i);// cerr << ans[i] << " ";}// cerr << endl;for (int i = 0; i < 4; i++) x = (x+(long long)M/a[i]*inv(M/a[i]%a[i], a[i])%M*ans[i]%M)%M;// cerr << x << endl;return x;}int n, g;int main(){scanf("%d%d", &n, &g);if (g%mod == 0) {puts("0");return 0;}for (int i = 0; i < 4; i++) fac[i][0] = ifac[i][0] = 1;for (int i = 0; i < 4; i++) {for (int j = 1; j < a[i]; j++)fac[i][j] = (long long)fac[i][j-1]*j%a[i];for (int j = 1; j < a[i]; j++)ifac[i][j] = (long long)ifac[i][j-1]*inv(j, a[i])%a[i];}// cerr << lucas(4, 1, 0) << endl;int ans = 0;for (int i = 1; i*i <= n; i++)if (n%i == 0) {ans = (ans+choose_mod(n, i))%M;if (n/i > i) ans = (ans+choose_mod(n, n/i))%M;}printf("%d\n", power(g, ans, mod));return 0;}
次多项式满足,则满足:
2780: [Spoj]8093 Sevenk Love Oimaster
题意:给定若干个模式串,多组询问,问有多少个模式串包含作为其子串。
对模式串建立广义后缀自动机。对于每一个模式串,找到他所有前缀的状态并在其集合中加入。这样,对于一个询问,先找到他的位置,然后答案就是其子树中set并的大小。可以用平衡树/启发式合并,或者线段树合并来维护。
#include <bits/stdc++.h>using namespace std;const int MAXN = 100005;struct SAM {int chl[MAXN][26], top, root, fa[MAXN], maxl[MAXN];set<int> right_set[MAXN];int pos[MAXN];int dp[MAXN];struct node {int to, next;} edge[MAXN];int head[MAXN], top_tp;inline void push_edge(int i, int j){ edge[++top_tp] = (node) {j, head[i]}, head[i] = top_tp; }void clear(){memset(chl, 0, sizeof chl), top_tp = top = root = 1;memset(fa, 0, sizeof fa), memset(maxl, 0, sizeof maxl);}SAM(){ clear(); }int push(int nd, int x){int p = nd, np = ++top; maxl[np] = maxl[p]+1;while (p && !chl[p][x]) chl[p][x] = np, p = fa[p];if (!p) fa[np] = root;else {int q = chl[p][x];if (maxl[q] == maxl[p]+1) fa[np] = q;else {int nq = ++top; maxl[nq] = maxl[p]+1, memcpy(chl[nq], chl[q], sizeof chl[q]);fa[nq] = fa[q], fa[q] = fa[np] = nq;while (p && chl[p][x] == q) chl[p][x] = nq, p = fa[p];}}return np;}int get_pos(char *str){int nd = root;for (char *p = str; *p != '\0'; ++p) {if (!chl[nd][*p-'a']) return -1;nd = chl[nd][*p-'a'];}return nd;}int merge(int a, int b){if (right_set[a].size() < right_set[b].size()) swap(a, b);for (set<int>::iterator j = right_set[b].begin(); j != right_set[b].end(); ++j)right_set[a].insert(*j);return a;}void dfs(int nd){for (int i = head[nd]; i; i = edge[i].next) {int to = edge[i].to;dfs(to);}for (int i = head[nd]; i; i = edge[i].next) {int to = edge[i].to;pos[nd] = merge(pos[nd], pos[to]);}dp[nd] = right_set[pos[nd]].size();}inline void get_ans(){for (int i = 1; i <= top; i++) {pos[i] = i;if (fa[i]) push_edge(fa[i], i);}dfs(root);}};struct trie {int chl[MAXN][26], fa[MAXN], stat[MAXN], top, root;SAM sam;int fin[MAXN], fin_top;void clear(){sam.clear(), fin_top = top = root = 0;memset(stat, 0, sizeof stat);}trie(){ clear(); }inline void push(int &nd, const char *str){if (!nd) nd = ++top;if (*str != '\0') push(chl[nd][*str-'a'], str+1), fa[chl[nd][*str-'a']] = nd;else fin[++fin_top] = nd;}inline void push(const char *str){ push(root, str); }queue<int> que;void build_sam(){stat[root] = sam.root, que.push(root);while (!que.empty()) {int nd = que.front(); que.pop();for (int i = 0; i < 26; i++) {if (!chl[nd][i]) continue;stat[chl[nd][i]] = sam.push(stat[nd], i);que.push(chl[nd][i]);}}}void paint(){for (int i = 1; i <= fin_top; i++) {for (register int j = fin[i]; j; j = fa[j])sam.right_set[stat[j]].insert(i);}}} T;int n, q;char s[400005];int pos[60005];int main(){scanf("%d%d", &n, &q);for (int i = 1; i <= n; i++) {scanf("%s", s);T.push(s);}T.build_sam();T.paint();for (int i = 1; i <= q; i++) {scanf("%s", s);pos[i] = T.sam.get_pos(s);}T.sam.get_ans();for (int i = 1; i <= q; i++) {if (pos[i] == -1) puts("0");else printf("%d\n", T.sam.dp[pos[i]]);}return 0;}
#include <bits/stdc++.h>using namespace std;const int MAXN = 8000005, N = 50005;int chl[MAXN][2], fa[MAXN], top = 0;int dat[MAXN];int root[N];int siz[MAXN];void update(int nd){ siz[nd] = (chl[nd][0]!=0)*siz[chl[nd][0]]+(chl[nd][1]!=0)*siz[chl[nd][1]]+1; }void zig(int nd, int id){int p = fa[nd], g = fa[p], tp = chl[p][0] != nd, tg = chl[g][0] != p;int son = chl[nd][tp^1];if (son) fa[son] = p;if (g) chl[g][tg] = nd;else root[id] = nd;fa[p] = nd, fa[nd] = g, chl[nd][tp^1] = p, chl[p][tp] = son;update(p), update(nd);}void splay(int nd, int id, int tar = 0){while (fa[nd] != tar) {// cerr << nd << " " << fa[nd] << endl;int p = fa[nd], g = fa[p], tp = chl[p][0] != nd, tg = chl[g][0] != p;if (g == tar) { zig(nd, id); break; }else if (tp == tg) zig(p, id), zig(nd, id);else zig(nd, id), zig(nd, id);}}int get_rank(int nd, int id){splay(nd, id);return chl[nd][0]+1;}int number_ls(int k, int id){int ans = 0, nd = root[id];while (nd) {if (dat[nd] < k) ans += siz[chl[nd][0]]+1, nd = chl[nd][1];else nd = chl[nd][0];}return ans;}int number_le(int k, int id){int ans = 0, nd = root[id];while (nd) {if (dat[nd] <= k) ans += siz[chl[nd][0]]+1, nd = chl[nd][1];else nd = chl[nd][0];}return ans;}int find_kth(int k, int id){int nd = root[id];while (1) {if (siz[chl[nd][0]]+1 == k) break;else if (siz[chl[nd][0]]+1 > k) nd = chl[nd][0];else k -= siz[chl[nd][0]]+1, nd = chl[nd][1];}splay(nd, id);return nd;}int pre_ele(int dt, int id){int ls = number_ls(dt, id);if (ls == 0) return 0;return find_kth(ls, id);}int nxt_ele(int dt, int id){int gt = number_le(dt, id)+1;if (gt > siz[root[id]]) return 0;return find_kth(gt, id);}int push(int &nd, int dt, int f = 0){if (nd == 0) {nd = ++top, dat[nd] = dt, update(nd);fa[nd] = f;return top;}siz[nd]++;if (dt <= dat[nd]) return push(chl[nd][0], dt, nd);else return push(chl[nd][1], dt, nd);}int pop_ele(int dt, int id){// printf("pop %d ---> %d\n", dt, id);int num = number_ls(dt, id)+1;// cerr << id << "j" << num << endl;int pre = find_kth(num-1, id), nxt = find_kth(num+1, id);// cerr << pre << " " << nxt << endl;// cerr << dat[nxt] << " " << dat[pre] << endl;splay(pre, id), splay(nxt, id, pre);chl[nxt][0] = 0, update(nxt), update(pre);// puts("---");}void push_ele(int dt, int id){// printf("push %d --> %d\n", dt, id);int nd = push(root[id], dt);splay(nd, id);}void display(int nd, int tab){if (!nd) return;for (int i = 1; i <= tab; i++) putchar(' ');printf("siz = %d, dat = %d\n", siz[nd], dat[nd]);display(chl[nd][0], tab+2), display(chl[nd][1], tab+2);}int c[N], a[N], n, m;inline int lowbit(int i){ return i&(-i); }void del(int nd, int dt){for (; nd <= n; nd += lowbit(nd))pop_ele(dt, nd);}void add(int nd, int dt){for (; nd <= n; nd += lowbit(nd))push_ele(dt, nd);}void modify(int nd, int dt){del(nd, a[nd]), add(nd, dt), a[nd] = dt;}int number_prefix_ls(int pos, int dt){int ans = 0;for (; pos; pos -= lowbit(pos))ans += number_ls(dt, pos)-1;return ans;}int number_seg_ls(int L, int R, int dt){ return number_prefix_ls(R, dt)-number_prefix_ls(L-1, dt); }int number_prefix_le(int pos, int dt){int ans = 0;for (; pos; pos -= lowbit(pos))ans += number_le(dt, pos)-1;return ans;}int number_seg_le(int L, int R, int dt){ return number_prefix_le(R, dt)-number_prefix_le(L-1, dt); }int find_seg_kth(int Lpos, int Rpos, int dt){int L = 0, R = 1e8, Mid;while (L <= R) {Mid = (L+R)>>1;if (number_seg_le(Lpos, Rpos, Mid) >= dt) R = Mid-1;else L = Mid+1;}return R+1;}int find_seg_pre(int Lpos, int Rpos, int dt){int num = number_seg_ls(Lpos, Rpos, dt);if (num == 0) return INT_MIN+1;return find_seg_kth(Lpos, Rpos, num);}int find_seg_nxt(int Lpos, int Rpos, int dt){int num = number_seg_le(Lpos, Rpos, dt)+1;if (num > Rpos-Lpos+1) return INT_MAX;return find_seg_kth(Lpos, Rpos, num);}inline int read(){int a = 0;scanf("%d", &a);return a;}int main(){// freopen("psh.in", "r", stdin);// freopen("psh.out", "w", stdout);n = read(), m = read();for (int i = 1; i <= n; i++) a[i] = read();for (int i = 1; i <= n; i++)push_ele(INT_MIN+1, i), push_ele(INT_MAX, i);for (int i = 1; i <= n; i++)add(i, a[i]);int cnt = 0;for (int i = 1; i <= m; i++) {int opt, l, r, k;opt = read();cnt++;if (opt == 1) {l = read(), r = read(), k = read();printf("%d\n", number_seg_ls(l, r, k)+1);} else if (opt == 2) {l = read(), r = read(), k = read();printf("%d\n", find_seg_kth(l, r, k));} else if (opt == 3) {l = read(), r = read();modify(l, r);cnt--;} else if (opt == 4) {l = read(), r = read(), k = read();printf("%d\n", find_seg_pre(l, r, k));} else {l = read(), r = read(), k = read();printf("%d\n", find_seg_nxt(l, r, k));}}return 0;}
#include <bits/stdc++.h>using namespace std;const int MAXN = 50005;struct node {int to, next;} edge[MAXN];int head[MAXN], top = 0;inline void push(int i, int j){ edge[++top] = (node) {j, head[i]}, head[i] = top; }int dfn[MAXN], dfn_top = 0, low[MAXN], vis[MAXN], stk[MAXN], stk_top = 0;int g[MAXN], gtop = 0, gsiz[MAXN];int d[MAXN];int n, m;void tarjan(int nd){stk[++top] = nd, vis[nd] = 1, dfn[nd] = low[nd] = ++dfn_top;for (int i = head[nd]; i; i = edge[i].next) {int to = edge[i].to;if (!dfn[to]) tarjan(to), low[nd] = min(low[nd], low[to]);else if (vis[to]) low[nd] = min(low[nd], dfn[to]);}if (dfn[nd] == low[nd]) {gtop++;int now;do {now = stk[top--];vis[now] = 0; // !!!g[now] = gtop, gsiz[gtop]++;} while (now != nd);}}int main(){scanf("%d%d", &n, &m);for (int i = 1; i <= m; i++) {int u, v;scanf("%d%d", &u, &v);push(u, v);}for (int i = 1; i <= n; i++)if (!dfn[i])tarjan(i);for (int i = 1; i <= n; i++) {for (int j = head[i]; j; j = edge[j].next) {int to = edge[j].to;d[g[i]] += (g[to] != g[i]);}}int pos = 0, cnt = 0;for (int i = 1; i <= gtop; i++)if (d[i] == 0) {pos = i, cnt++;}if (cnt != 1) puts("0");else printf("%d\n", gsiz[pos]);return 0;}
#include <bits/stdc++.h>using namespace std;const int MAXN = 1000005;char S[MAXN], T[MAXN];int nxt[MAXN];int main(){scanf("%s", S+1), scanf("%s", T+1);nxt[1] = 0;int pL = strlen(T+1), sL = strlen(S+1), cnt = 0;int p = 0;for (int i = 2; i <= pL; i++) {while (p && T[p+1] != T[i]) p = nxt[p];if (T[p+1] == T[i]) p++;nxt[i] = p;}p = 0;for (int i = 1; i <= sL; i++) {while (p && T[p+1] != S[i]) p = nxt[p];if (T[p+1] == S[i]) p++;if (p == pL) {cnt++;p = nxt[p];}}printf("%d\n", cnt);return 0;}
#include <bits/stdc++.h>using namespace std;const int MAXN = 1000005;struct SA {struct node {int k[2], id;node(){}node(int x, int y) {k[0] = x, k[1] = y; }} RE[MAXN], RT[MAXN];int a[MAXN], sum[MAXN], SA[MAXN], rank[MAXN], n;void radix_sort(){for (int y = 1; y >= 0; y--) {memset(sum, 0, sizeof sum);for (int i = 1; i <= n; i++) RT[i] = RE[i];for (int i = 1; i <= n; i++) sum[RT[i].k[y]]++;for (int i = 1; i < MAXN; i++) sum[i] += sum[i-1];for (int i = n; i >= 1; i--) RE[sum[RT[i].k[y]]--] = RT[i];}for (int i = 1; i <= n; i++) {rank[RE[i].id] = rank[RE[i-1].id];if (RE[i].k[0] != RE[i-1].k[0] || RE[i].k[1] != RE[i-1].k[1])rank[RE[i].id]++;}}void build_SA(){for (int i = 1; i <= n; i++) RE[i] = node(a[i], 0), RE[i].id = i;radix_sort();for (int k = 1; k < n; k <<= 1) {for (int j = 1; j <= n; j++) RE[j] = node(rank[j], j+k<=n?rank[j+k]:0), RE[j].id = j;radix_sort();}for (int i = 1; i <= n; i++)SA[rank[i]] = i;}} sa;char str[MAXN];int main(){scanf("%s", str+1);sa.n = strlen(str+1);for (int i = 1; i <= sa.n; i++) sa.a[i] = str[i];sa.build_SA();for (int i = 1; i <= sa.n; i++)printf("%d ", sa.SA[i]);puts("");return 0;}
#include <bits/stdc++.h>using namespace std;const int MAXN = 100005;int have0 = 0;struct linear_base {long long a[70];int top;linear_base(){ top = 0; }void push(long long x){for (int i = 1; i <= top; i++)if ((x^a[i]) < x)x ^= a[i];if (!x) { have0 = 1; return; }a[++top] = x;int i = top;for (; i > 1 && a[i] > a[i-1]; i--)swap(a[i], a[i-1]);for (i--; i >= 1; i--)if ((x^a[i]) < a[i])a[i] ^= x;}} lb;int main(){int n, m;long long x;scanf("%d", &n);for (int i = 1; i <= n; i++) {scanf("%lld", &x), lb.push(x);// for (int i = 1; i <= lb.top; i++) cerr << lb.a[i] << " ";// cerr << endl;}// puts("hahahahaha");// cerr << lb.top << endl;scanf("%d", &m);for (int i = 1; i <= m; i++) {scanf("%lld", &x);x -= have0;if (x > (1ll<<lb.top)) puts("-1");else {// cerr << "--" << x << " " << lb.top << endl;// cerr << lb.a[9] << endl;long long ans = 0;for (int j = 0; j <= 60; j++)if (x&(1ll<<j)) {ans ^= lb.a[lb.top-j];// cerr << lb.top-j << endl;}printf("%lld\n", ans);}}return 0;}
行列建点,增广路对应方案。
#include <bits/stdc++.h>using namespace std;const int MAXN = 205;int n, m, k;int l[MAXN], c[MAXN];struct node {int to, next, flow, cost, neg;} edge[MAXN*MAXN*10];int head[MAXN], top = 0;inline void push(int i, int j, int f, int c){++top, edge[top] = (node) {j, head[i], f, c, top+1}, head[i] = top;++top, edge[top] = (node) {i, head[j], 0, -c, top-1}, head[j] = top;}const int SS = MAXN-1, ST = MAXN-2, S = MAXN-3, T = MAXN-4;int cnt = 0;inline void push(int i, int j, int lb){push(SS, j, lb, 0), push(i, ST, lb, 0);cnt += lb;}int dis[MAXN], vis[MAXN];deque<int> que;bool spfa(){memset(dis, 127/3, sizeof dis);memset(vis, 0, sizeof vis);vis[SS] = 1, dis[SS] = 0, que.push_back(SS);while (!que.empty()) {int nd = que.front(); que.pop_front(), vis[nd] = 0;for (int i = head[nd]; i; i = edge[i].next) {int to = edge[i].to, f = edge[i].flow, c = edge[i].cost;if (!f || dis[to] <= dis[nd]+c) continue;dis[to] = dis[nd]+c;if (!vis[to]) {vis[to] = 1;if (que.empty() || dis[to] > dis[que.front()]) que.push_back(to);else que.push_front(to);}}}return dis[ST] <= 23333333;}int dfs(int nd, int flow){if (nd == ST || !flow) return flow;vis[nd] = 1;int ans = 0, t;for (int i = head[nd]; i; i = edge[i].next) {int to = edge[i].to, f = edge[i].flow, c = edge[i].cost;if (vis[to] || dis[to] != dis[nd]+c || !f) continue;t = dfs(to, min(flow, f));ans += t, flow -= t, edge[i].flow -= t, edge[edge[i].neg].flow += t;if (!flow) break;}return ans;}void mcf(int &c, int &f){c = f = 0;int t;while (spfa()) {do {memset(vis, 0, sizeof vis);t = dfs(SS, INT_MAX);f += t, c += t*dis[ST];} while (t);}}bool g[101][101];int main(){scanf("%d%d%d", &n, &m, &k);for (int i = 1; i <= n; i++) scanf("%d", &l[i]);for (int i = 1; i <= m; i++) scanf("%d", &c[i]);for (int i = 1; i <= k; i++) {int u, v;scanf("%d%d", &u, &v);g[u][v] = true;}for (int i = 1; i <= n; i++) push(S, i, l[i]);for (int j = 1; j <= m; j++) push(n+j, T, c[j]);for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++)if (!g[i][j])push(i, n+j, 1, 1);push(T, S, INT_MAX, 0);int c, f;mcf(c, f);if (f != cnt) puts("JIONG!");else printf("%d\n", c);return 0;}
TODO LIST: