模板

#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);
}
posted @ 2021-12-05 09:13  Linshey  阅读(77)  评论(0编辑  收藏  举报