模板
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100010;
int n,m,op,x,y;
int lc[maxn],rc[maxn],dist[maxn],rt[maxn];
bool tf[maxn];
struct node
{
int id,v;
bool operator<(node x)const{return v==x.v?id<x.id:v<x.v;}
}v[maxn];
int find(int x){return rt[x]==x?x:rt[x]=find(rt[x]);}
int merge(int x,int y)
{
if(!x||!y)return x+y;
if(v[y]<v[x])swap(x,y);
rc[x]=merge(rc[x],y);
if(dist[lc[x]]<dist[rc[x]])swap(lc[x],rc[x]);
dist[x]=dist[rc[x]]+1;
return x;
}
int main()
{
dist[0]=-1;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&v[i].v),rt[i]=i,v[i].id=i;
while(m--)
{
scanf("%d%d",&op,&x);
if(op==1)
{
scanf("%d",&y);
if(tf[x]||tf[y])continue;
x=find(x);y=find(y);
if(x!=y)rt[x]=rt[y]=merge(x,y);
}
if(op==2)
{
if(tf[x]){printf("-1\n");continue;}
x=find(x);
printf("%d\n",v[x].v);
tf[x]=true;
rt[lc[x]]=rt[rc[x]]=rt[x]=merge(lc[x],rc[x]);
lc[x]=rc[x]=dist[x]=0;
}
}
return 0;
}
未完待续……(只是给自己存个板子)
快速傅里叶变换
#include <bits/stdc++.h>
using namespace std; const int maxn = 2e6 + 1e2;
struct Cp
{
double x, y;
inline Cp operator +(const Cp& b) const { return (Cp) { x + b.x, y + b.y }; }
inline Cp operator -(const Cp& b) const { return (Cp) { x - b.x, y - b.y }; }
inline Cp operator *(const Cp& b) const { return (Cp) { x * b.x - y * b.y, x * b.y + y * b.x }; }
};
namespace fft
{
int l, r[maxn], lim = 1; long double Pi = acos(-1.0); inline void init(int n)
{
while (lim <= n) lim <<= 1, l++; for (int i = 0; i < lim; i++)
{
r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
}
}
inline void fft(Cp A[], int v)
{
for (int i = 0; i < lim; i++) if (i < r[i]) swap(A[i], A[r[i]]);
Cp Wn, w, x, y; for (int mid = 1; mid < lim; mid <<= 1)
{
Wn = (Cp) { cos(Pi / mid), v * sin(Pi / mid) }; for (int R = mid << 1, j = 0; j < lim; j += R)
{
w = (Cp) { 1, 0 }; for (int k = 0; k < mid; k++, w = w * Wn)
{
x = A[j + k], y = w * A[j + mid + k], A[j + k] = x + y, A[j + mid + k] = x - y;
}
}
}
for (int i = 0; i < lim; i++) (v > 0) ? (A[i].x /= lim, A[i].y /= lim) : (A[i].x *= lim, A[i].y /= lim);
}
inline void conv(Cp A[], Cp B[], Cp C[]) { for (int i = 0; i < lim; i++) C[i] = A[i] * B[i]; }
}
Cp A[maxn], B[maxn], C[maxn]; int n, m; int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0), cin >> n >> m;
for (int i = 0; i <= n; i++) cin >> A[i].x;
for (int i = 0; i <= m; i++) cin >> B[i].x;
fft::init(n + m), fft::fft(A, 1), fft::fft(B, 1), fft::conv(A, B, C), fft::fft(C, -1);
for (int i = 0; i <= n + m; i++) cout << int(C[i].x + 0.5) << ' '; return 0;
}
快速数论变换:
#include <bits/stdc++.h>
using namespace std; const int maxn = 5e5 + 1e2, mod = 998244353, g = 3, h = 332748118;
namespace fft
{
int l, r[maxn], lim = 1; inline void init(int n)
{
while (lim <= n) lim <<= 1, l++; for (int i = 0; i < lim; i++)
{
r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
}
}
inline int fpow(int x, int k)
{
int res = 1; while (k) { if (k & 1) res = 1ll * res * x % mod; x = 1ll * x * x % mod; k >>= 1; } return res;
}
inline void fft(int A[], int v)
{
for (int i = 0; i < lim; i++) if (i < r[i]) swap(A[i], A[r[i]]);
int Wn, w, x, y; for (int mid = 1; mid < lim; mid <<= 1)
{
Wn = fpow(v == 1 ? g : h, (mod - 1) / (mid << 1)); for (int R = mid << 1, j = 0; j < lim; j += R)
{
w = 1; for (int k = 0; k < mid; k++, w = 1ll * w * Wn % mod)
{
y = 1ll * w * A[j + mid + k] % mod, A[j + mid + k] = (A[j + k] - y) % mod, A[j + k] = (A[j + k] + y) % mod;
}
}
}
int inv = fpow(lim, mod - 2);
for (int i = 0; i < lim; i++) (v > 0) ? (A[i] = A[i] * 1ll * inv % mod) : (A[i] = A[i] * 1ll * lim % mod);
}
inline void conv(int A[], int B[], int C[]) { for (int i = 0; i < lim; i++) C[i] = 1ll * A[i] * B[i] % mod; }
}
int A[maxn], B[maxn], C[maxn]; int n, m; int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0), cin >> n >> m;
for (int i = 0; i <= n; i++) cin >> A[i];
for (int i = 0; i <= m; i++) cin >> B[i];
fft::init(n + m), fft::fft(A, 1), fft::fft(B, 1), fft::conv(A, B, C), fft::fft(C, -1);
for (int i = 0; i <= n + m; i++) cout << (C[i] + mod) % mod << ' '; return 0;
}
快速莫比乌斯/沃尔什变换:
namespace fwt
{
int lim; inline void init(int n) { lim = 1; while (lim < n) lim <<= 1; }
inline void OR(modint f[], modint t)
{
for (int mid = 1; mid < lim; mid <<= 1) for (int R = (mid << 1), j = 0; j < lim; j += R)
for (int k = 0; k < mid; k++) f[j + k + mid] += f[j + k] * t;
}
inline void AND(modint f[], modint t)
{
for (int mid = 1; mid < lim; mid <<= 1) for (int R = (mid << 1), j = 0; j < lim; j += R)
for (int k = 0; k < mid; k++) f[j + k] += f[j + k + mid] * t;
}
inline void XOR(modint f[], modint t)
{
for (int mid = 1; mid < lim; mid <<= 1) for (int R = (mid << 1), j = 0; j < lim; j += R)
for (int k = 0; k < mid; k++)
{
f[j + k] += f[j + mid + k], f[j + mid + k] = f[j + k] - f[j + mid + k] - f[j + mid + k], f[j + k] *= t, f[j + mid + k] *= t;
}
}
inline void CONV(modint A[], modint B[], modint C[]) { for (int i = 0; i < lim; i++) C[i] = A[i] * B[i]; }
}
modint 类(乱入):
int ttmp; struct modint
{
int x; modint(int o) { x = o; } modint() { x = 0; }
inline modint &operator =(int o) { return x = o, *this; }
inline modint &operator +=(modint b) { return x = (ttmp = x + b.x) >= mod ? ttmp - mod : ttmp, *this; }
inline modint &operator -=(modint b) { return x = (ttmp = x - b.x) < 0 ? ttmp + mod : ttmp, *this; }
inline modint &operator *=(modint b) { return x = 1ll * x * b.x % mod, *this; }
inline modint operator ^(int k)
{
modint res = 1, xx = x; while (k) { if (k & 1) res *= xx; k >>= 1, xx = xx * xx; } return res;
}
inline modint operator /=(modint b) { return x = 1ll * x * ((b ^ (mod - 2)).x) % mod, *this; }
inline modint operator /=(int b) { return x = 1ll * x * (modint(b) ^ (mod - 2)).x, *this; }
inline modint operator +(modint b) const { return modint((ttmp = x + b.x) >= mod ? ttmp - mod : ttmp); }
inline modint operator -(modint b) const { return modint((ttmp = x - b.x) < 0 ? ttmp + mod : ttmp); }
inline modint operator *(modint b) const { return modint(1ll * x * b.x % mod); }
inline modint operator /(modint b) const { return modint(1ll * x * ((b ^ (mod - 2)).x) % mod); }
};
多项式乘法逆:
#include <bits/stdc++.h>
using namespace std; const int maxn = 1e6 + 1e2, mod = 998244353, G = 3, gi = 332748118;
namespace ntt
{
int lim, l, r[maxn]; inline void init(int n)
{
lim = 1, l = 0; while (lim <= n) lim <<= 1, l++; for (int i = 0; i < lim; i++)
{
r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
}
}
inline int qpow(int x, int k)
{
int res = 1; while (k) { if (k & 1) res = 1ll * res * x % mod; x = 1ll * x * x % mod, k >>= 1; } return res;
}
inline void ntt(int A[], int type)
{
for (int i = 0; i < lim; i++) if (i < r[i]) swap(A[i], A[r[i]]);
int Wn, w, y, mid, j, k, R; for (mid = 1; mid < lim; mid <<= 1)
{
Wn = qpow(type == 1 ? G : gi, (mod - 1) / (mid << 1)); for (j = 0, R = (mid << 1); j < lim; j += R)
{
w = 1; for (k = 0; k < mid; k++, w = 1ll * w * Wn % mod)
{
y = A[j + k + mid] * 1ll * w % mod, A[j + k + mid] = (A[j + k] - y) % mod, A[j + k] = (A[j + k] + y) % mod;
}
}
}
int inv = qpow(lim, mod - 2);
for (int i = 0; i < lim; i++) (type == 1) ? (A[i] = A[i] * 1ll * inv % mod) : (A[i] = A[i] * 1ll * lim % mod);
}
int A[maxn], B[maxn]; inline void conv(int a[], int b[], int C[], int n, int m, int k)
{
for (int i = 0; i <= n; i++) A[i] = a[i];
for (int i = 0; i <= m; i++) B[i] = b[i];
init(n + m), ntt(A, 1), ntt(B, 1); for (int i = 0; i < lim; i++) C[i] = 1ll * A[i] * B[i] % mod;
ntt(C, mod - 1); for (int i = k; i < lim; i++) C[i] = 0;
for (int i = 0; i < lim; i++) A[i] = B[i] = 0;
}
}
int t[maxn]; inline void PolyInv(int f[], int g[], int n)
{
if (n == 1) { g[0] = ntt::qpow(f[0], mod - 2); return; }
int m = (n + 1) >> 1; PolyInv(f, g, m);
ntt::conv(f, g, t, n - 1, m - 1, n);
for (int i = 0; i < n; i++) t[i] = -t[i]; t[0] += 2;
ntt::conv(g, t, g, m - 1, n - 1, n);
}
int f[maxn], g[maxn], n;
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0), cin >> n;
for (int i = 0; i < n; i++) cin >> f[i]; PolyInv(f, g, n);
for (int i = 0; i < n; i++) cout << (g[i] + mod) % mod << ' '; return 0;
}
多项式开根(接在逆元的后面):
int u[maxn]; inline void PolySqrt(int f[], int g[], int n)
{
if (n == 1) { g[0] = 1; return; }
int m = (n + 1) >> 1; PolySqrt(f, g, m);
PolyInv(g, u, n), ntt::conv(u, f, u, n - 1, n - 1, n);
int inv = ntt::qpow(2, mod - 2);
for (int i = 0; i < n; i++) g[i] = (g[i] + u[i]) * 1ll * inv % mod;
}
子集卷积:
#include <bits/stdc++.h>
using namespace std; const int maxn = 1 << 22, mod = 1e9 + 9;
inline void fwt(int f[], int n, int t)
{
for (int mid = 1; mid < (1 << n); mid <<= 1) for (int j = 0, R = (mid << 1); j < (1 << n); j += R)
for (int k = 0; k < mid; k++) (f[j + k + mid] += f[j + k] * t) %= mod;
}
int n, a[21][maxn], b[21][maxn], c[21][maxn], t[maxn];
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0), cin >> n;
for (int i = 0; i < (1 << n); i++) cin >> a[__builtin_popcount(i)][i];
for (int i = 0; i < (1 << n); i++) cin >> b[__builtin_popcount(i)][i];
for (int i = 0; i <= n; i++) fwt(a[i], n, 1), fwt(b[i], n, 1);
for (int i = 0; i <= n; i++) for (int j = 0; j <= n - i; j++)
{
for (int k = 0; k < (1 << n); k++) (c[i + j][k] += a[i][k] * 1l * b[j][k] % mod) %= mod;
}
for (int i = 0; i <= n; i++) fwt(c[i], n, -1);
for (int i = 0; i < (1 << n); i++) cout << (c[__builtin_popcount(i)][i] + mod) % mod << ' ';
}
Ln & Exp 指数 / 对数函数
int v[maxn]; inline void PolyLn(int f[], int g[], int n)
{
PolyInv(f, g, n); for (int i = 1; i < n; i++) v[i - 1] = f[i] * 1ll * i % mod;
ntt::conv(v, g, g, n - 2, n - 1, n);
for (int i = n - 1; i; i--) g[i] = g[i - 1] * 1ll * ntt::qpow(i, mod - 2) % mod; g[0] = 0;
}
int w[maxn]; inline void PolyExp(int f[], int g[], int n)
{
if (n == 1) { g[0] = 1; return ; }
int m = (n + 1) >> 1; PolyExp(f, g, m);
PolyLn(g, w, n); for (int i = 0; i < n; i++) w[i] = (- w[i] + f[i]) % mod; w[0]++;
ntt::conv(w, g, g, n - 1, m - 1, n);
}
未完待续……敬请期待(bushi
圆方树(会在两圆点间建方点):
void tarjan(int u)
{
low[u] = dfn[u] = ++dfc, stk[++top] = u, num++;
for (int v : G[u]) if (!dfn[v])
{
tarjan(v), low[u] = std::min(low[u], low[v]);
if (low[v] == dfn[u])
{
++ncr; for (int x = 0; x != v; --top)
{
x = stk[top], T[ncr].push_back(x), T[x].push_back(ncr), val[ncr]++;
}
T[ncr].push_back(u), T[u].push_back(ncr), val[ncr]++;
}
}
else low[u] = std::min(low[u], dfn[v]);
}
仙人掌(不建的版本):
inline void calc(int u, int v, int val)
{
ncr++; int tmp = val, i = v; while (i != fa[u])
{
sum[i] = tmp, tmp += res[i], i = fa[i];
}
sum[ncr + n] = sum[u], i = v, sum[u] = 0; while (i != fa[u])
{
tmp = min(sum[i], sum[ncr + n] - sum[i]);
T[ncr + n].insert(T[ncr + n].begin(), Edge { i, tmp });
T[i].insert(T[i].begin(), Edge { ncr + n, tmp }); i = fa[i];
}
}
void Tarjan(int u, int f)
{
dfn[u] = low[u] = ++dfc; for (Edge v : G[u])
{
if (!dfn[v.to])
{
fa[v.to] = u, res[v.to] = v.vl, Tarjan(v.to, u), low[u] = min(low[u], low[v.to]);
}
else if (v.to != f) low[u] = min(low[u], dfn[v.to]);
if (low[v.to] > dfn[u]) T[u].push_back(v), T[v.to].push_back(Edge{ u, v.vl });
}
for (Edge v : G[u]) if (fa[v.to] != u && dfn[v.to] > dfn[u]) calc(u, v.to, v.vl);
}
#include <bits/stdc++.h>
using namespace std; const int maxn = 1e6 + 1e2;
char s[maxn]; int n, SA[maxn], rk[maxn];
int id[maxn], px[maxn], cnt[maxn], lrk[maxn << 1];
bool cmp(int x, int y, int w) { return lrk[x] == lrk[y] && lrk[x + w] == lrk[y + w]; }
inline void SAsort()
{
n = strlen(s + 1); int i, m = 128, p, w;
for (i = 1; i <= n; i++) ++cnt[rk[i] = s[i]];
for (i = 1; i <= m; i++) cnt[i] += cnt[i - 1];
for (i = n; i >= 1; i--) SA[cnt[rk[i]]--] = i;
for (w = 1; w < n; w <<= 1, m = p)
{
for (p = 0, i = n; i > n - w; --i) id[++p] = i;
for (i = 1; i <= n; ++i) if (SA[i] > w) id[++p] = SA[i] - w;
memset(cnt, 0, sizeof cnt);
for (i = 1; i <= n; ++i) ++cnt[px[i] = rk[id[i]]];
for (i = 1; i <= m; i++) cnt[i] += cnt[i - 1];
for (i = n; i >= 1; --i) SA[cnt[px[i]]--] = id[i];
memcpy(lrk, rk, sizeof rk);
for (p = 0, i = 1; i <= n; ++i) rk[SA[i]] = cmp(SA[i], SA[i - 1], w) ? p : ++p;
}
}
int main()
{
scanf("%s", s + 1); SAsort(); for (int i = 1; i <= n; i++) cout << SA[i] << ' ';
}
#include <bits/stdc++.h>
using namespace std;
const int MAX=100010;
int n,m,u,v,del[MAX];
int du[MAX][2];//记录入度和出度
stack <int> st;
vector <int> G[MAX];
void dfs(int now)
{
for(int i=del[now];i<G[now].size();i=del[now])
{
del[now]=i+1;
dfs(G[now][i]);
}
st.push(now);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++) scanf("%d%d",&u,&v),G[u].push_back(v),du[u][1]++,du[v][0]++;
for(int i=1;i<=n;i++) sort(G[i].begin(),G[i].end());
int S=1,cnt[2]={0,0}; //记录
bool flag=1; //flag=1表示,所有的节点的入度都等于出度,
for(int i=1;i<=n;i++)
{
if(du[i][1]!=du[i][0]) flag=0;
if(du[i][1]-du[i][0]==1/*出度比入度多1*/) cnt[1]++,S=i;
if(du[i][0]-du[i][1]==1/*入度比出度多1*/) cnt[0]++;
}
if((!flag)&&!(cnt[0]==cnt[1]&&cnt[0]==1)) return !printf("No");
//不满足欧拉回路的判定条件,也不满足欧拉路径的判定条件,直接输出"No"
dfs(S);
while(!st.empty()) printf("%d ",st.top()),st.pop();
return 0;
}
#include <iostream>
#include <unordered_map>
using namespace std; const int maxn = 2216727; typedef long long ll;
unordered_map<int, int> Smu; int pr[maxn], tt, mu[maxn]; bool isp[maxn];
inline void prework()
{
mu[1] = 1; for (int i = 2; i < maxn; i++)
{
if (!isp[i]) pr[++tt] = i, mu[i] = -1;
for (int j = 1, t; j <= tt && ((t = i * pr[j]) < maxn); j++)
{
isp[t] = true; if (i % pr[j] == 0) continue; mu[t] = -mu[i];
}
}
for (int i = 1; i < maxn; i++) mu[i] += mu[i - 1];
}
inline int QSmu(int n)
{
if (Smu[n]) return Smu[n]; if (n < maxn) return mu[n]; int rs = 0;
for (unsigned int l = 2, r; l <= n; l = r + 1)
{
r = n / (n / l); rs -= QSmu(n / l) * (r - l + 1);
}
return Smu[n] = 1 + rs;
}
inline ll QSph(int n)
{
ll ans = 0; for (unsigned int l = 1, r; l <= n; l = r + 1)
{
r = n / (n / l), ans += 1ll * (QSmu(r) - QSmu(l - 1)) * (n / l) * (n / l);
}
return ans;
}
int main()
{
prework(); int T, n; cin >> T; while (T--)
{
cin >> n; cout << (QSph(n) - 1) / 2 + 1 << " " << QSmu(n) << endl;
}
return 0;
}
\[g(1)S(n)=\sum\limits_{i=1}^{n}(f*g)(i) - \sum \limits _{i=2}^{n} g(i) S(\lfloor \frac{n}{i} \rfloor)
\]
#include <bits/stdc++.h>
using namespace std; typedef unsigned long long ll;
//inline int popcount(ll x) { int rs = 0; while ((x & (1ull << rs)) == 0) rs++; return rs; }
inline ll gcd(register ll x, register ll y)
{
if (!x || !y) return x | y; register int t = __builtin_ctzll(x | y); x >>= __builtin_ctzll(x);
do { y >>= __builtin_ctzll(y); if (x > y) swap(x, y); y -= x; } while (y); return x << t;
}
ll mul(ll x, ll y, ll P) { ll z = x * y - (ll)((long double)x / P * y + 0.5L) * P; return z < P ? z : z + P; }
inline ll qpow(ll x, ll k, ll md) { ll rs = 1; while (k) { if (k & 1) rs = mul(rs, x, md); x = mul(x, x, md), k >>= 1; } return rs; }
inline bool test(ll x, ll b)
{
ll k = x - 1; while (k)
{
ll cur = qpow(b, k, x);
if ((cur != 1) & (cur != x - 1)) return 0;
if ((k & 1) | (cur == x - 1)) return 1;
k >>= 1;
}
return 1;
}
inline bool Miller_Rabin(ll x)
{
if (x == 46856248255981ll || x < 2 || ((x & 1) ^ (x > 2))) return 0;
if (x == 2 || x == 3 || x == 7 || x == 61 || x == 24251) return 1;
return test(x, 2) && test(x, 61);
}
unsigned int seed = 2333333;
unsigned int Random() { return seed ^= seed << 13, seed ^= seed >> 17, seed ^= seed << 5; }
ll abs(ll x, ll y) { return x < y ? y - x : x - y; }
inline ll Pollar_Rho(ll x)
{
register ll s = 0, t = 0, c = (Random() % x + x) % (x - 1) + 1, vl = 1, d;
for (register int st, hl = 1; ; s = t, hl <<= (vl = 1))
{
for (st = 1; st <= hl; st++)
{
t = (mul(t, t, x) + c) % x;
vl = mul(vl, abs(s, t), x);
if (st % 127 == 0 && ((d = gcd(vl, x)) > 1))
return d;
}
if ((d = gcd(vl, x)) > 1)
return d;
}
}
ll mx;
void divide(ll x)
{
if (x < 2 || x <= mx) return;
if (Miller_Rabin(x)) { mx = x; return; }
ll p = x; while (p == x) p = Pollar_Rho(p);
while (x % p < 1) x /= p;
divide(x), divide(p);
}
void solve()
{
ll x; scanf("%llu", &x);
if (Miller_Rabin(x)) return void(puts("Prime"));
mx = 0, divide(x);
//if (m == 1) return void(puts("Prime"));
printf("%llu\n", mx);
}
int main()
{
int T; scanf("%d", &T); while (T--) solve();
return 0;
}
#include <cstdio>
#include <algorithm>
using namespace std; const int maxn = 5e5 + 5;
int val[maxn], rnd[maxn], sze[maxn], ch[maxn][2], tt;
int New(int v) { return val[++tt] = v, rnd[tt] = rand(), sze[tt] = 1, tt; }
void Maintain(int u) { sze[u] = sze[ch[u][0]] + sze[ch[u][1]] + 1; }
int Merge(int x, int y)
{
if (!x || !y) return x | y; else
{
if (rnd[x] > rnd[y]) { ch[x][1] = Merge(ch[x][1], y), Maintain(x); return x; }
else { ch[y][0] = Merge(x, ch[y][0]), Maintain(y); return y; }
}
}
void Split(int u, int k, int& x, int& y)
{
if (!u) x = y = 0; else
{
if (val[u] <= k) x = u, Split(ch[u][1], k, ch[x][1], y), Maintain(u);
else y = u, Split(ch[u][0], k, x, ch[y][0]), Maintain(u);
}
}
int kth(int u, int k)
{
while (233)
{
if (sze[ch[u][0]] + 1 > k) u = ch[u][0];
else if (sze[ch[u][0]] + 1 == k) return u;
else k -= sze[ch[u][0]] + 1, u = ch[u][1];
}
}
int main()
{
int n, opt, v, rt = 0, x, y, z; scanf("%d", &n); while (n--)
{
scanf("%d%d", &opt, &v);
if (opt == 1) { Split(rt, v, x, y), rt = Merge(Merge(x, New(v)), y); }
else if (opt == 2) { Split(rt, v, x, z), Split(x, v - 1, x, y), rt = Merge(Merge(x, Merge(ch[y][0], ch[y][1])), z); }
else if (opt == 3) { Split(rt, v - 1, x, y), printf("%d\n", sze[x] + 1), rt = Merge(x, y); }
else if (opt == 4) { printf("%d\n", val[kth(rt, v)]); }
else if (opt == 5) { Split(rt, v - 1, x, y), printf("%d\n", val[kth(x, sze[x])]), rt = Merge(x, y); }
else { Split(rt, v, x, y), printf("%d\n", val[kth(y, 1)]), rt = Merge(x, y); }
}
return 0;
}
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = 2e5 + 5;
int ch[maxn][2], fa[maxn], sz[maxn], ct[maxn], rt;
inline void pushup(int u) { sz[u] = sz[ch[u][0]] + sz[ch[u][1]] + ct[u]; }
inline void rotate(int u)
{
int v = fa[u], g = fa[v], z = ch[v][1] == u, h = ch[u][z ^ 1];
fa[fa[fa[ch[ch[ch[g][ch[g][1] == v] = u][z ^ 1] = v][z] = h] = v] = u] = g;
pushup(v), pushup(u);
}
inline void splay(int u, int f = 0)
{
if (!f) rt = u;
for (int v = fa[u]; (v = fa[u]) != f; rotate(u)) if (fa[v] != f) rotate(ch[fa[v]][1] == v ^ ch[v][1] == u ? u : v);
}
void init(int n) { rt = 1; for (int i = 1; i <= n; i++) fa[ch[i][1] = i + 1] = i; }
int kth(int u, int k)
{
while (233)
{
if (sz[ch[u][0]] >= k) u = ch[u][0];
else if (k - sz[ch[u][0]] <= ct[u]) { splay(u); return u; }
else k -= sz[ch[u][0]] + ct[u], u = ch[u][1];
}
}
void insert(int u, int d) { if (u) splay(u - 1); splay(u + 1, u - 1), ct[u] += d, pushup(u), pushup(u - 1); }
int n, k[maxn], x[maxn], y[maxn];
int main()
{
scanf("%d", &n), init(n);
for (int i = 1; i <= n; i++) scanf("%d%d", k + i, x + i);
memcpy(y, x, sizeof x), sort(y + 1, y + n + 1);
for (int i = 1; i <= n; i++) if (k[i] != 4) x[i] = lower_bound(y + 1, y + n + 1, x[i]) - y;
for (int i = 1, tp; i <= n; i++)
{
if (k[i] == 1) insert(x[i], 1); else if (k[i] == 2) insert(x[i], -1);
else if (k[i] == 3) splay(x[i]), printf("%d\n", sz[ch[x[i]][0]] + 1);
else if (k[i] == 4) printf("%d\n", y[kth(rt, x[i])]);
else if (k[i] == 5) splay(x[i]), printf("%d\n", y[kth(ch[x[i]][0], sz[ch[x[i]][0]])]);
else splay(x[i]), printf("%d\n", y[kth(ch[x[i]][1], 1)]);
}
}
#include <bits/stdc++.h>
using namespace std; typedef long long ll;
namespace dinic
{
const int N = 1e3 + 5, M = 1e5 + 5;
int n, m, S, T, q[N], t, h, it[N], lev[N];
int to[M], nx[M], hd[N], tt = 1; ll cap[M];
inline void add(int u, int v, ll w) { to[++tt] = v, nx[tt] = hd[u], hd[u] = tt, cap[tt] = w; }
inline void link(int u, int v, ll w) { add(u, v, w), add(v, u, 0); }
inline bool bfs()
{
memset(lev, 0, 4 * (n + 1)), lev[q[t = h = 0] = S] = 1; int i, u, v;
while (h <= t) for (i = hd[u = q[h++]]; i; i = nx[i])
if (cap[i] && !lev[v = to[i]]) lev[v] = lev[u] + 1, q[++t] = v;
return lev[T];
}
ll dfs(int u, ll f)
{
if (u == T) return f; ll res = 0, z; int v;
for (int& i = it[u]; i; i = nx[i])
if (cap[i] && lev[v = to[i]] == lev[u] + 1 && (z = dfs(v, min(f - res, cap[i]))))
{
cap[i] -= z, cap[i ^ 1] += z, res += z; if (res == f) break;
}
return res;
}
ll Dinic()
{
ll res = 0, z;
while (bfs())
{
memcpy(it, hd, 4 * (n + 1));
while (z = dfs(S, 1e18)) res += z;
}
return res;
}
}
using namespace dinic;
int main()
{
scanf("%d%d%d%d", &n, &m, &S, &T);
for (int i = 1, u, v, w; i <= m; i++) scanf("%d%d%d", &u, &v, &w), link(u, v, w);
printf("%lld\n", Dinic());
}
#include <bits/stdc++.h>
using namespace std; const int maxn = 605; typedef long long ll;
int a[maxn][maxn], n, p;
int main()
{
scanf("%d%d", &n, &p);
for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) scanf("%d", &a[i][j]);
int res = 1;
for (int j = 1; j <= n; j++)
{
for (int i = j; i <= n; i++) if (a[i][j]) { if (i != j) res *= -1, swap(a[i], a[j]); }
for (int i = j + 1; i <= n; i++) if (a[i][j])
{
while (a[i][j])
{
int kk = a[i][j] / a[j][j];
for (int k = j; k <= n; k++)
{
a[i][k] = ((a[i][k] - (ll)kk * a[j][k]) % p + p) % p;
}
// cerr << a[i][j] << ' ' << a[j][j] << endl;
if (!a[i][j]) break;
swap(a[j], a[i]), res = -res;
}
}
if (!a[j][j]) { res = 0; break; } res = (ll)res * a[j][j] % p;
}
printf("%d\n", (res + p) % p);
}
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e2 + 5, maxm = 1e3 + 5;
struct Edge { int to, nx, vl; } G[maxm]; int hd[maxn], tt;
inline void addEdge(int u, int v, int w)
{
G[++tt] = Edge{ v, hd[u], w }; hd[u] = tt;
}
priority_queue<pair<int, int> > q;
int dp[maxn][1 << 11], n, m, k, p[maxn]; bool vis[maxn];
inline void dijkstra(int S)
{
memset(vis, 0, n + 1); int i, v, w; pair<int, int> x; while (!q.empty())
{
x = q.top(); q.pop(); if (vis[x.second]) continue;
vis[x.second] = true; for (i = hd[x.second]; i; i = G[i].nx)
if (dp[v = G[i].to][S] > -x.first + (w = G[i].vl))
{
q.push(make_pair(-(dp[v][S] = -x.first + w), v));
}
}
}
int main()
{
memset(dp, 63, sizeof dp);
ios::sync_with_stdio(0), cin.tie(0), cin >> n >> m >> k; int u, v, w;
while (m--) cin >> u >> v >> w, addEdge(u, v, w), addEdge(v, u, w);
for (int i = 1; i <= k; i++) cin >> p[i], dp[p[i]][1 << i - 1] = 0;
for (int S = 1, i, nS; S < (1 << k); S++)
{
for (i = 1; i <= n; i++)
{
for (nS = S & (S - 1); nS; nS = S & (nS - 1))
{
dp[i][S] = min(dp[i][S], dp[i][nS] + dp[i][S ^ nS]);
}
if (dp[i][S] < 1e8) q.push(make_pair(-dp[i][S], i));
}
dijkstra(S);
}
cout << dp[p[1]][(1 << k) - 1] << endl; return 0;
}
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = 2e6 + 5;
int cnt = 1, lst = 1, fa[maxn], len[maxn], sze[maxn], ch[maxn][26];
void insert(char c)
{
c -= 'a'; int p = lst, q = ++cnt; len[lst = q] = len[p] + (sze[q] = 1);
while (p && !ch[p][c]) ch[p][c] = q, p = fa[p]; if (!p) fa[q] = 1; else
{
int x = ch[p][c]; if (len[x] == len[p] + 1) fa[q] = x; else
{
int y = ++cnt; fa[y] = fa[x], fa[x] = fa[q] = y, len[y] = len[p] + 1;
memcpy(ch[y], ch[x], 104); while (p && ch[p][c] == x) ch[p][c] = y, p = fa[p];
}
}
}
char s[maxn]; int n, a[maxn], c[maxn], as;
int main()
{
scanf("%s", s + 1), n = strlen(s + 1);
for (int i = 1; i <= n; i++) insert(s[i]);
for (int i = 1; i <= cnt; i++) c[len[i]]++;
for (int i = 1; i <= n; i++) c[i] += c[i - 1];
for (int i = 1; i <= cnt; i++) a[c[len[i]]--] = i;
for (int i = cnt; i; i--) sze[fa[a[i]]] += sze[a[i]];
for (int i = 1; i <= cnt; i++) if (sze[i] > 1) as = max(as, sze[i] * len[i]);
printf("%d\n", as); return 0;
}
#include <cstdio>
#include <cstring>
using namespace std; const int maxn = 5e5 + 5;
namespace PAM
{
char s[maxn]; int n;
int cnt, lst, len[maxn], ch[maxn][26], fa[maxn], dp[maxn];
void init()
{
cnt = 1, fa[0] = 1, len[1] = -1, n = lst = len[0] = fa[1] = 0;
}
int get(int x)
{
while (s[n - len[x] - 1] != s[n]) x = fa[x]; return x;
}
void insert(char c)
{
s[++n] = c; int p = get(lst), x; if (!ch[p][c - 'a'])
{
len[x = ++cnt] = len[p] + 2, dp[x] = dp[fa[x] = ch[get(fa[p])][c - 'a']] + 1, ch[p][c - 'a'] = x;
}
lst = ch[p][c - 'a'];
}
}
char s[maxn]; int n;
int main()
{
scanf("%s", s + 1), n = strlen(s + 1), PAM::init();
for (int i = 1; i <= n; i++)
{
PAM::insert((s[i] - 97 + PAM::dp[PAM::lst]) % 26 + 97), printf("%d ", PAM::dp[PAM::lst]);
}
return 0;
}
#include <iostream>
using namespace std; const int maxn = 1e5 + 5;
int fa[maxn], ch[maxn][2], rv[maxn], sm[maxn], vl[maxn], sk[maxn];
void Maintain(int u) { sm[u] = sm[ch[u][0]] ^ sm[ch[u][1]] ^ vl[u]; }
void Reverse(int u) { rv[u] ^= 1, swap(ch[u][0], ch[u][1]); }
void Spread(int u) { if (rv[u]) { if (ch[u][0]) Reverse(ch[u][0]); if (ch[u][1]) Reverse(ch[u][1]); rv[u] = 0; } }
bool Judge(int u) { return ch[fa[u]][0] == u || ch[fa[u]][1] == u; }
void Rotate(int x)
{
int y = fa[x], z = fa[y], k = ch[y][1] == x, w = ch[x][!k];
if (Judge(y)) ch[z][ch[z][1] == y] = x;
ch[x][!k] = y, ch[y][k] = w, fa[x] = z, fa[y] = x, fa[w] = y, Maintain(y);
}
void Splay(int x)
{
int y = x, z = 0; sk[++z] = y;
while (Judge(y)) sk[++z] = y = fa[y]; while (z) Spread(sk[z--]);
while (Judge(x)) { y = fa[x], z = fa[y]; if (Judge(y)) Rotate((ch[y][0] == x) ^ (ch[z][0] == y) ? x : y); Rotate(x); }
Maintain(x);
}
void Access(int x) { for (int y = 0; x; x = fa[y = x]) Splay(x), ch[x][1] = y, Maintain(x); }
void MakeRoot(int x) { Access(x), Splay(x), Reverse(x); }
int FindRoot(int x) { Access(x), Splay(x); while (ch[x][0]) Spread(x), x = ch[x][0]; Splay(x); return x; }
void Split(int x, int y) { MakeRoot(x), Access(y), Splay(y); }
void Link(int x, int y) { MakeRoot(x); if (FindRoot(x) != FindRoot(y)) fa[x] = y; }
void Cut(int x, int y) { MakeRoot(x); if (FindRoot(y) == x && fa[y] == x && !ch[y][0]) fa[y] = ch[x][1] = 0, Maintain(x); }
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, m, t, x, y; cin >> n >> m; for (int i = 1; i <= n; i++) cin >> vl[i];
while (m--)
{
cin >> t >> x >> y;
if (t == 0) { Split(x, y), cout << sm[y] << endl; }
else if (t == 1) { Link(x, y); }
else if (t == 2) { Cut(x, y); }
else { Splay(x), vl[x] = y, Maintain(x); }
}
}
#include <bits/stdc++.h>
using namespace std; const int maxn = 2e3 + 5, mod = 998244353; typedef long long ll;
vector<int> tr[maxn << 2]; int n, X, px[maxn], py[maxn];
void update(int u, int l, int r, int ul, int ur, int k)
{
if (ul <= l && r <= ur) { tr[u].push_back(k); return; } int mid = l + r >> 1;
if (ul <= mid) update(u << 1, l, mid, ul, ur, k); if (ur > mid) update(u << 1 | 1, mid + 1, r, ul, ur, k);
}
int f[20][maxn], as[maxn];
int qpow(int x, int k) { int res = 1; while (k) { if (k & 1) res = (ll)res * x % mod; x = (ll)x * x % mod, k >>= 1; } return res; }
void solve(int d, int u, int l, int r)
{
memcpy(f[d], f[d - 1], sizeof(int) * (n + 1));
for (int x : tr[u]) { for (int j = n; j; j--) f[d][j] = (f[d][j - 1] - (ll)f[d][j] * x) % mod; f[d][0] = (ll)f[d][0] * (-x) % mod; }
if (l == r)
{
int kk = 1; for (int i = 1; i <= n; i++) if (i != l) kk = (ll)kk * (px[l] - px[i]) % mod;
kk = (ll)qpow(kk, mod - 2) * py[l]% mod;
for (int i = 0; i <= n; i++) as[i] = (as[i] + (ll)kk * f[d][i]) % mod;
}
else
{
int mid = l + r >> 1; solve(d + 1, u << 1, l, mid), solve(d + 1, u << 1 | 1, mid + 1, r);
}
}
int main()
{
scanf("%d%d", &n, &X);
for (int i = 1; i <= n; i++) scanf("%d%d", px + i, py + i);
for (int i = 2; i <= n; i++) update(1, 1, n, 1, i - 1, px[i]);
for (int i = 1; i < n; i++) update(1, 1, n, i + 1, n, px[i]);
f[0][0] = 1; solve(1, 1, 1, n);
int Y = 1, res = 0;
for (int i = 0; i <= n; i++) res = (res + (ll)Y * as[i]) % mod, Y = (ll)X * Y % mod;
printf("%lld\n", (res + mod) % mod);
}
#include <bits/stdc++.h>
typedef long long ll; using namespace std;
const int maxn = 2e3 + 5, mod = 998244353;
inline ll qpow(ll x, ll k)
{
ll res = 1; while (k)
{
if (k & 1) res = res * x % mod; x = x * x %mod, k >>= 1;
}
return res;
}
int x[maxn], y[maxn], k, n;
int main()
{
cin >> n >> k;
for (int i = 1; i <= n; i++) cin >> x[i] >> y[i];
int ans = 0, t[maxn]; for (int i = 1; i <= n; i++) t[i] = 1;
for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++)
{
if (i != j) t[i] = (k - x[j]) * qpow(x[i] - x[j], mod - 2) % mod * t[i] % mod;
}
for (int i = 1; i <= n; i++) ans = (ans + y[i] * 1ll * t[i] % mod) % mod;
cout << (ans % mod + mod) % mod << endl;
return 0;
}
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; typedef long long ll;
namespace dinic
{
const int N = 5e3 + 5, M = 5e5 + 5;
int n, m, S, T, q[N], t, h; ll lev[N]; bool ok[N];
int to[M], nx[M], hd[N], tt = 1; ll cap[M], wt[M], ans;
void add(int u, int v, ll c, ll w)
{
to[++tt] = v, nx[tt] = hd[u], hd[u] = tt, cap[tt] = c, wt[tt] = w;
}
void link(int u, int v, ll c, ll w) { add(u, v, c, w), add(v, u, 0, -w); }
bool bfs()
{
memset(lev, 63, 8 * n + 8), memset(ok, 0, n + 1), lev[q[t = h = 0] = S] = 0; int i, u, v;
while (h <= t) for (i = hd[u = q[h++ % N]], ok[u] = 0; i; i = nx[i])
if (cap[i] && lev[v = to[i]] > lev[u] + wt[i])
{
lev[v] = lev[u] + wt[i]; if (!ok[v]) ok[q[++t % N] = v] = 1;
}
return lev[T] < 1e18;
}
ll dfs(int u, ll f)
{
if (ok[u] = 1, u == T) return f; int i, v; ll res = 0, z;
for (i = hd[u]; i; i = nx[i])
if (cap[i] && lev[v = to[i]] == lev[u] + wt[i] && !ok[v] && (z = dfs(v, min(cap[i], f - res))))
{
res += z, cap[i] -= z, cap[i ^ 1] += z, ans += wt[i] * z; if (res == f) break;
}
return res;
}
void Dinic()
{
ll res = 0;
while (bfs()) do memset(ok, 0, n + 1), res += dfs(S, 1e18); while (ok[T]);
printf("%lld %lld\n", res, ans);
}
}
using namespace dinic;
int main()
{
scanf("%d%d%d%d", &n, &m, &S, &T); int u, v, c, w;
while (m--) scanf("%d%d%d%d", &u, &v, &c, &w), link(u, v, c, w);
Dinic(); return 0;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define int long long
using namespace std;
const int maxn = 1e6;
int n, c[maxn][26], val[maxn], nxt[maxn], cnt;
char s[maxn];
void ins()
{
int len = strlen(s + 1), u = 0;
for (int i = 1; i <= len; i++)
{
int v = s[i] - 'a';
if (!c[u][v]) c[u][v] = ++cnt;
u = c[u][v];
}
val[u]++;
}
void build()
{
queue<int> q;
for (int i = 0; i < 26; i++)
if (c[0][i])
{
q.push(c[0][i]);
}
while (q.size())
{
int u = q.front(); q.pop();
for (int i = 0; i < 26; i++)
{
if (c[u][i])
{
q.push(c[u][i]);
nxt[c[u][i]] = c[nxt[u]][i];
}
else
{
c[u][i] = c[nxt[u]][i];
}
}
}
}
int query()
{
int len = strlen(s + 1), u = 0, ans = 0;
for (int i = 1; i <= len; i++)
{
u = c[u][s[i] - 'a'];
for (int t = u; t && val[t] != -1; t = nxt[t])
{
ans += val[t];
val[t] = -1;
}
}
return ans;
}
signed main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
//scanf("%s", s + 1);
cin >> s + 1;
ins();
}
build();
//scanf("%s", s + 1);
cin >> s + 1;
cout << query() << endl;
return 0;
}
#include <bits/stdc++.h>
typedef long long ll;
using namespace std; const int maxn = 1e5 + 5;
ll mul(ll x, ll y, ll P)
{
ll z = x * y - (ll)((long double)x / P * y + 0.5L) * P; return z < P ? z : z + P;
}
ll gcd(ll x, ll y)
{
return !y ? x : gcd(y, x % y);
}
pair<ll, ll> exgcd(ll a, ll b)
{
if (!b) return make_pair(1, 0); pair<ll, ll> x = exgcd(b, a % b);
return make_pair(x.second, x.first - a / b * x.second);
}
ll a[maxn], b[maxn]; int n;
inline void exCRT()
{
ll x = 0, M = 1; for (int i = 1; i <= n; i++)
{
if ((a[i] - x) % gcd(M, b[i])) exit(0 * puts("no solution!"));
pair<ll, ll> t = exgcd(M, b[i]); ll bg = gcd(M, b[i]);
t.first = mul(t.first, (a[i] - x) / bg, b[i]);
x += t.first * M; x %= (M = M / bg * b[i]);
}
cout << (x % M + M) % M << endl;
}
int main()
{
cin >> n; for (int i = 1; i <= n; i++) cin >> b[i] >> a[i]; exCRT();
}
/*
inline void exCRT()
{
ll x = 0, M = 1; for (int i = 1; i <= n; i++)
{
if ((a[i] - x) % gcd(M, b[i])) exit(0 * puts("no solution!"));
pair<ll, ll> t = exgcd(M, b[i]); ll bg = gcd(M, b[i]);
t.first = mul(t.first, (a[i] - x) / bg, b[i]);
x += a[i] - mul(t.first, M, M = M / bg * b[i]);
}
cout << x << endl;
}
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = 2e6 + 5; typedef long long ll;
int cnt = 1, len[maxn], fa[maxn], ch[maxn][26];
int insert(int lst, char c)
{
c -= 'a'; if (ch[lst][c])
{
int p = lst, x = ch[lst][c]; if (len[x] == len[p] + 1) return x;
else
{
int y = ++cnt; fa[y] = fa[x], fa[x] = y, memcpy(ch[y], ch[x], 104);
len[y] = len[p] + 1; while (p && ch[p][c] == x) ch[p][c] = y, p = fa[p]; return y;
}
}
int p = lst, q = ++cnt; len[q] = len[p] + 1;
while (p && !ch[p][c]) ch[p][c] = q, p = fa[p]; if (!p) fa[q] = 1; else
{
int x = ch[p][c]; if (len[x] == len[p] + 1) fa[q] = x;
else
{
int y = ++cnt; fa[y] = fa[x], fa[x] = fa[q] = y, memcpy(ch[y], ch[x], 104);
len[y] = len[p] + 1; while (p && ch[p][c] == x) ch[p][c] = y, p = fa[p];
}
}
return q;
}
int n, m; char s[maxn];
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%s", s + 1), m = strlen(s + 1);
for (int p = 1, j = 1; j <= m; j++) p = insert(p, s[j]);
}
ll as = 0; for (int i = 2; i <= cnt; i++) as += len[i] - len[fa[i]]; printf("%lld\n", as);
}
as 0.4123