inlineboolBFS(){ queue<int> Q; Q.push(S); vis[S] = ++Time, depth[S] = 0; while (!Q.empty()) { int u = Q.front(); Q.pop(); for (int i = head[u]; ~i; i = edges[i].nxt) { const Edge& e = edges[i]; if (vis[e.to] != Time && e.cap > e.flow) vis[e.to] = Time, depth[e.to] = depth[u] + 1, Q.push(e.to); } } return vis[T] == Time; }
intDFS(int u, int a){ if (u == T || !a) return a; int f, flow = 0; for (int& i = cur[u]; ~i; i = edges[i].nxt) { Edge& e = edges[i]; if (depth[e.to] == depth[u] + 1 && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0) { flow += f, a -= f, e.flow += f, edges[i^1].flow -= f; if (!a) break; } } return flow; }
inlineintMaxflow(){ int flow = 0; while (BFS()) memcpy(cur, head, sizeof cur), flow += DFS(S, INF); return flow; } }
namespace SCC { usingnamespace Dinic; int dfn[MAXV], low[MAXV], SCCidx[MAXV], SCCcnt, dfs_clock; int stk[MAXV], top;
voidtarjan(int u){ low[u] = dfn[u] = ++dfs_clock, stk[++top] = u; for (int v, i = head[u]; ~i; i = edges[i].nxt) { // 残量 if (edges[i].flow == edges[i].cap) continue; if (!dfn[v = edges[i].to]) { tarjan(v); low[u] = min(low[u], low[v]); } elseif (!SCCidx[v]) low[u] = min(low[u], dfn[v]); } if (low[u] == dfn[u]) { ++SCCcnt; while (true) { int x = stk[top--]; SCCidx[x] = SCCcnt; if (u == x) break; } } }
inlinevoidsolve(){ for (int u = 1; u <= n + 2; ++u) if (!dfn[u]) tarjan(u); for (int i = 1; i <= m; ++i) { constint &u = E[i].first, &v = E[i].second; if (SCCidx[u] == SCCidx[v] || edges[id[i]].flow < 1) continue; Ans.push_back(E[i]); } } }
intmain(){ #ifndef ONLINE_JUDGE freopen("input.in", "r", stdin); #endif // init Graph::init(), Dinic::init(); // input read(n), read(m); S = n + 1, T = n + 2; for (int u, v, i = 1; i <= m; ++i) { read(u), read(v); if (u > v) swap(u, v); E[i] = Pii(u, v); Graph::AddEdge(u, v), Graph::AddEdge(v, u); } // solve for (int u = 1; u <= n; ++u) if (col[u] == 0) col[u] = 1, Graph::dfs(u); for (int i = 1; i <= m; ++i) { constint &u = E[i].first, &v = E[i].second; if (col[u] == 1) id[i] = Dinic::AddEdge(u, v, 1); if (col[u] == 2) id[i] = Dinic::AddEdge(v, u, 1); } for (int u = 1; u <= n; ++u) { if (col[u] == 1) Dinic::AddEdge(S, u, 1); if (col[u] == 2) Dinic::AddEdge(u, T, 1); } Dinic::Maxflow(); SCC::solve(); // output printf("%lu\n", Ans.size()); sort(Ans.begin(), Ans.end()); for (size_t i = 0; i < Ans.size(); ++i) printf("%d %d\n", Ans[i].first, Ans[i].second); return0; }
inlineintpls(constint& a, constint& b){ return (a + b < P)? a + b: a + b - P; } inlineintmns(constint& a, constint& b){ return (a - b >= 0)? a - b: a - b + P; }
structItem { LL x, y, z; booloperator < (const Item& rhs) const { return (x == rhs.x)? ((y == rhs.y)? z < rhs.z: y < rhs.y): x < rhs.x; } } A[MAXO];
LL n, m, r, o; int Bit[BASE + 1]; int C[MAXN][MAXN], f[MAXN][MAXN][MAXN], g[MAXO];
// 通过预处理, 计算一个 long long 范围数的 popcount inline LL lowbit(const LL& x){ return x & -x; } inlineint __brute_popcount(LL x) { int ret = 0; while (x > 0) ++ret, x -= lowbit(x); return ret; }
voidgetFail(){ queue<int> Q; fail[1] = 1; for (int c = 0; c < SIGMA; ++c) { int& v = ch[c][1]; if (v) Q.push(v), fail[v] = 1; else v = 1; } while (!Q.empty()) { int u = Q.front(); Q.pop(); for (int c = 0; c < SIGMA; ++c) { int& v = ch[c][u]; if (v) Q.push(v), fail[v] = ch[c][fail[u]]; else v = ch[c][fail[u]]; } } for (int i = 2; i <= AC::nidx; ++i) Graph::AddEdge(fail[i], i); } }
structBIT { int C[MAXN];
inlineintlowbit(constint& x){ return x & -x; }
inlinevoidMdy(constint& d, constint& val){ for (int i = d; i <= Graph::dfs_clock; i += lowbit(i)) C[i] += val; }
inlineintQry(constint& d){ int ret = 0; for (int i = d; i; i -= lowbit(i)) ret += C[i]; return ret; } inlineintQry(constint& L, constint& R){ returnQry(R) - Qry(L-1); } } T[2];
voidsolve(int u){ usingnamespace Graph; for (size_t i = 0; i < Q[u].size(); ++i) { const Ask& q = Q[u][i]; Ans[q.idx] -= q.type * T[q.type < 0].Qry(dfn[q.nd], dfn[q.nd] + size[q.nd] - 1); } for (size_t i = 0; i < M[u].size(); ++i) { const Ask& m = M[u][i]; T[m.type < 0].Mdy(dfn[m.nd], 1); } for (int i = head[u]; ~i; i = edges[i].nxt) solve(edges[i].to); for (size_t i = 0; i < Q[u].size(); ++i) { const Ask& q = Q[u][i]; Ans[q.idx] += q.type * T[q.type < 0].Qry(dfn[q.nd], dfn[q.nd] + size[q.nd] - 1); } }
inlineintval(constchar& c){ return c - 33; }
intmain(){ #ifndef ONLINE_JUDGE freopen("input.in", "r", stdin); #endif // init AC::init(), Graph::init(); // input scanf("%d%s%d", &K, S + 1, &n); int Slgt = (int) strlen(S + 1); for (int j = 1; j <= n; ++j) { scanf("%s", P + 1); int Plgt = (int) strlen(P + 1); // 80pts = = if (Plgt <= K) { Ans[j] = Slgt - Plgt + 1; continue; } // AC-automaton for (int u = 1, i = 1; i <= Plgt; ++i) pos[0][i] = u = AC::insert(u, val(P[i])); for (int u = 1, i = Plgt; i >= 1; --i) pos[1][i] = u = AC::insert(u, val(P[i])); // maintain pos[0][0] = pos[1][Plgt + 1] = 1; for (int i = 0; i <= Plgt - K; ++i) Q[pos[0][i]].push_back(Ask(1, j, pos[1][i + K + 1])); for (int i = 1; i <= Plgt - K; ++i) Q[pos[0][i]].push_back(Ask(-1, j, pos[1][i + K])); } // solve AC::getFail(), Graph::dfs(1); // match pos[0][0] = pos[1][Slgt + 1] = 1; for (int i = 1; i <= Slgt; ++i) pos[0][i] = AC::ch[val(S[i])][pos[0][i - 1]]; for (int i = Slgt; i >= 1; --i) pos[1][i] = AC::ch[val(S[i])][pos[1][i + 1]]; // maintain for (int i = 0; i <= Slgt - K; ++i) M[pos[0][i]].push_back(Ask(1, 0, pos[1][i + K + 1])); for (int i = 1; i <= Slgt - K; ++i) M[pos[0][i]].push_back(Ask(-1, 0, pos[1][i + K])); solve(1); // output for (int i = 1; i <= n; ++i) printf("%d\n", Ans[i]); return0; }
structModify { int u, v, L, R; bitset<MAXL> w; } M[MAXM];
int n, m, q, top; char str[MAXL];
bitset<MAXL> fix(char* S){ bitset<MAXL> ret; int lgt = (int) strlen(S); reverse(S, S + lgt); for (int i = 0; i < lgt; ++i) ret[i] = S[i] - '0'; return ret; }
structLinerBasis { bitset<MAXL> A[MAXL];
LinerBasis() { for (int i = 0; i < MAXL; ++i) A[i].reset(); }
inlinevoidinsert(bitset<MAXL> x){ for (int i = MAXL-1; i >= 0; --i) if (x[i]) { if (!A[i].any()) { A[i] = x; break; } x ^= A[i]; } }
inlinevoidQry(){ // max xor bitset<MAXL> ret; ret.reset(); for (int i = MAXL-1; i >= 0; --i) if (!ret[i]) ret ^= A[i]; // output int i = MAXL-1; while (i > 0 && !ret[i]) --i; while (i >= 0) putchar(ret[i--] + '0'); putchar('\n'); } };
namespace DSU { int fa[MAXN], size[MAXN]; bitset<MAXL> dist[MAXN];
inlinevoidinit(){ for (int i = 1; i <= n; ++i) fa[i] = i, size[i] = 1, dist[i].reset(); }
inlineintfindfa(int u){ while (u != fa[u]) u = fa[u]; return u; } inline bitset<MAXL> findist(int u){ bitset<MAXL> ret; ret.reset(); while (u != fa[u]) ret ^= dist[u], u = fa[u]; return ret; } }
// LOJ #2313 // DeP #include<cstdio> #include<algorithm> usingnamespace std;
constint MAXN = 1e5+5;
structAsk { int idx, L, R; booloperator < (const Ask& rhs) const { return R < rhs.R || (R == rhs.R && L < rhs.L); } } Q[MAXN];
int n, q; char S[MAXN]; int pos[MAXN], Ans[MAXN];
namespace SAM { constint MAXN = ::MAXN << 1, SIGMA = 2; int ch[SIGMA][MAXN], lnk[MAXN], len[MAXN], nidx, last; int idx[MAXN], Lidx[MAXN], MaxLCP;
inlinevoidinit(){ nidx = last = 1; }
inlineintinsert(int val){ int nd = ++nidx, p = last; len[nd] = len[last] + 1; while (p && !ch[val][p]) ch[val][p] = nd, p = lnk[p]; if (!p) lnk[nd] = 1; else { int q = ch[val][p]; if (len[q] == len[p] + 1) lnk[nd] = q; else { int nxt = ++nidx; len[nxt] = len[p] + 1, lnk[nxt] = lnk[q]; ch[0][nxt] = ch[0][q], ch[1][nxt] = ch[1][q]; while (p && ch[val][p] == q) ch[val][p] = nxt, p = lnk[p]; lnk[q] = lnk[nd] = nxt; } } return last = nd; }
inlinevoidUpd(int R){ for (int u = pos[R]; u > 1; u = lnk[u]) { if (idx[u]) { MaxLCP = max(MaxLCP, len[u]); Lidx[len[u]] = max(Lidx[len[u]], idx[u]); } idx[u] = max(idx[u], R); } }
inlineintQry(int L){ int ret = 0; for (int lst = L - 1, i = MaxLCP; i >= 1; --i) if (lst < Lidx[i]) ret += i * (Lidx[i] - lst), lst = Lidx[i]; return ret; } }
intmain(){ #ifndef ONLINE_JUDGE freopen("input.in", "r", stdin); #endif // init SAM::init(); // input scanf("%d%d%s", &n, &q, S+1); for (int L, R, i = 1; i <= q; ++i) scanf("%d%d", &L, &R), Q[i] = (Ask){ i, L, R }; // solve for (int i = n; i; --i) pos[i] = SAM::insert(S[i] - '0'); sort(Q+1, Q+1+q); for (int idx = 1, i = 1; i <= n; ++i) { SAM::Upd(i); while (idx <= q && Q[idx].R <= i) Ans[Q[idx].idx] = SAM::Qry(Q[idx].L), ++idx; } // output for (int i = 1; i <= q; ++i) printf("%d\n", Ans[i]); return0; }