板子们

数学

高斯消元(P2455)
#include<cstdio>
#include<cstring>

using namespace std;

int n;
double a[105][105];
void swap(double &x,double &y){double t = x; x = y; y = t;}
double abs(double x){return x > 0 ? x : -x;}
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]);
	int op = 1, i;
	for(i = 1; i <= n; ++i){
		int k = op;
		double mx = abs(a[op][i]);
		for(int j = op + 1; j <= n; ++j)if(abs(a[j][i]) > mx){
			mx = abs(a[j][i]);
			k = j;
		}
		if(mx == 0)continue;
		if(k != op)for(int j = 1; j <= n + i; ++j)swap(a[op][j], a[k][j]);
		for(int j = n + 1; j >= i; --j)a[op][j] /= a[op][i];
		for(int j = 1; j <= n; ++j)
			if(j != op)
				for(int p = n + 1; p >= i; --p)a[j][p] -= a[op][p] * a[j][i];
		++op;
	}
	if(op > n){
		for(int i = 1; i <= n; ++i){
			printf("x%d=",i);
			printf("%.2lf\n",a[i][n + 1]);
		}
	}else{
		bool flag = 0;
		for(int i = op; i <= n; ++i)if(a[i][n + 1]){flag = 1; break;}
		if(flag)printf("-1\n");
		else printf("0\n");
	}
	return 0;
}

多项式

fwt/fmt(and or xor)
void fwt_or(int f[], int opt){
	opt = (opt + mod) % mod;
	for(int l = 2, k = 1; l <= len; l <<= 1, k <<= 1)
		for(int i = 0; i < len; i += l)
			for(int j = 0; j < k; ++j)
				f[i + j + k] = (f[i + j + k] + 1ll * opt * f[i + j] % mod) % mod;
}
void fwt_and(int f[], int opt){
	opt = (opt + mod) % mod;
	for(int l = 2, k = 1; l <= len; l <<= 1, k <<= 1)
		for(int i = 0; i < len; i += l)
			for(int j = 0; j < k; ++j)
				f[i + j] = (f[i + j] + 1ll * f[i + j + k] * opt % mod) % mod;
}
void fwt_xor(int f[], int opt){
	opt = opt == -1 ? inv2 : 1;
	for(int l = 2, k = 1; l <= len; l <<= 1, k <<= 1)
		for(int i = 0; i < len; i += l)
			for(int j = 0; j < k; ++j){
				int x = f[i + j], y = f[i + j + k];
				f[i + j] = 1ll * opt * (x + y) % mod;
				f[i + j + k] = 1ll * opt * (x - y + mod) % mod;
			}
}
子集卷积
#include<map>
#include<bits/stdc++.h>

using namespace std;

int read(){
	int x = 0; char c = getchar();
	while(!isdigit(c))c = getchar();
	do{x = x * 10 + (c ^ 48); c = getchar();}while(isdigit(c));
	return x;
}
const int mod = 1e9 + 9;
const int maxn = (1 << 21) + 55;
int deg;
void add(int &x, int y){x += y; if(x >= mod)x -= mod;}
void fwt_or(int f[], int deg, int opt){
	for(int l = 2, hl = 1; l <= deg; l <<= 1, hl <<= 1)
		for(int i = 0; i < deg; i += l)
			for(int j = i; j < i + hl; ++j)
				add(f[j + hl], 1ll * f[j] * opt % mod);
}
int n, f[22][maxn], g[22][maxn], h[22][maxn], cnt[maxn];
int main(){
	n = read(); deg = 1 << n;
	for(int i = 1; i < deg; ++i)cnt[i] = cnt[i >> 1] + (i & 1);
	for(int i = 0; i < deg; ++i)f[cnt[i]][i] = read();
	for(int i = 0; i < deg; ++i)g[cnt[i]][i] = read();
	for(int i = 0; i <= n; ++i)fwt_or(f[i], deg, 1), fwt_or(g[i], deg, 1);
	for(int i = 0; i <= n; ++i)
		for(int j = 0; j <= i; ++j)
			for(int k = 0; k < deg; ++k)
				add(h[i][k], 1ll * f[j][k] * g[i - j][k] % mod);
	for(int i = 0; i <= n; ++i)fwt_or(h[i], deg, mod - 1);
	for(int i = 0; i < deg; ++i)printf("%d ",h[cnt[i]][i]);printf("\n");
	return 0;
}

fft
inline void fft(complex <double> a[], int len){
	for(register int i = 1; i < len; ++i)if(i < rev[i]) swap(a[i], a[rev[i]]);
	for(register int l = 2; l <= len; l <<= 1){
		complex <double> wn(cos(2 * PI / l), sin(2 * PI / l));
		for(register int j = 0; j < len; j += l){
			complex <double> w(1, 0);
			int ll = l >> 1;
			for(register int k = j; k < j + ll; ++k){
				complex <double> x = a[k];
				complex <double> y = w * a[k + ll];
				a[k] = x + y;
				a[k + ll] = x - y;
				w = w * wn;
			}
		}
	}
}
inline void ifft(complex <double> a[], int len){
	fft(a, len); reverse(a + 1, a + len);
	for(register int i = 0; i < len; ++i)a[i].imag(a[i].imag() / len);
}
inline void getrev(int len){
	for(register int i = 0; i < len; ++i){
		rev[i] =  rev[i >> 1] >> 1;
		if(i & 1)rev[i] |= len >> 1;
	}
}

四次mtt

mtt
const ld PI = acos(-1);
struct comp{
	ld x, y;
	friend comp operator * (const comp &x, const comp &y){return {x.x * y.x - x.y * y.y, x.x * y.y + x.y * y.x};}
	friend comp operator + (const comp &x, const comp &y){return {x.x + y.x, x.y + y.y};}
	friend comp operator - (const comp &x, const comp &y){return {x.x - y.x, x.y - y.y};}
	friend comp operator / (const comp &x, const ld &n){return {x.x / n, x.y / n};}
	friend comp operator * (const comp &x, const ld &n){return {x.x * n, x.y *n};}
	void operator /= (const ld &n){x /= n; y /= n;}
	comp conj(){return {x, -y};}
}wn[maxn], I = {0, 1};
int deg, rev[maxn];
void init(int len){
	deg = 1; while(deg < len)deg <<= 1;
	wn[0] = {1, 0}; 
	for(int i = 1; i < deg; ++i){
		wn[i] = {cos(2.0 * PI * i / deg), sin(2.0 * PI * i / deg)};
		rev[i] = rev[i >> 1] >> 1;
		if(i & 1)rev[i] |= (deg >> 1);
	}
}
struct poly{
	comp f[maxn];
	comp &operator [](const int &i){return f[i];}
	void fft(){
		for(int i = 1; i < deg; ++i)if(i < rev[i])swap(f[i], f[rev[i]]);
		for(int l = 2, hl = 1; l <= deg; l <<= 1, hl <<= 1)
			for(int i = 0; i < deg; i += l){
				comp x, y;
				for(int j = i; j < i + hl; ++j){
					x = f[j], y = wn[deg / l * (j - i)] * f[j + hl];
					f[j] = x + y; f[j + hl] = x - y;
				}
			}
	}
	void ifft(){fft(); reverse(f + 1, f + deg); for(int i = 0; i < deg; ++i)f[i] /= deg;}
}a0, a1, b0, b1, p, q;
void FFT(poly &x, poly &y){
	for(int i = 0; i < deg; ++i)x[i] = {x[i].x, y[i].x}; x.fft();
	for(int i = 0; i < deg; ++i)y[i] = x[i ? deg - i : 0].conj();
	for(int i = 0; i < deg; ++i){comp a = x[i], b = y[i]; x[i] = (a + b) * 0.5; y[i] = (b - a) * 0.5 * I;}
}
int n, m, mod, base, ans[maxn];
ll num(ld x){return x > 0 ? ((ll)(x + 0.5)) % mod : ((ll)(x - 0.5)) % mod;}
int main(){
	n = read(), m = read(); mod = read(); base = sqrt(mod) + 1; init(n + m + 1);
	for(int i = 0; i <= n; ++i){int x = read() % mod; a0[i].x = x / base; a1[i].x = x % base;} FFT(a0, a1);
	for(int i = 0; i <= m; ++i){int x = read() % mod; b0[i].x = x / base; b1[i].x = x % base;} FFT(b0, b1);
	for(int i = 0; i < deg; ++i)p[i] = I * a0[i] * b0[i] + a1[i] * b0[i], q[i] = a0[i] * b1[i] + I * a1[i] * b1[i];
	p.ifft(); q.ifft();
	for(int i = 0; i <= n + m; ++i)printf("%lld ",(num(p[i].y) * base % mod * base % mod + (num(p[i].x) + num(q[i].x)) % mod * base % mod + num(q[i].y)) % mod);
	printf("\n"); return 0;
}
ntt
const int mod = 998244353;
ll qpow(ll x, ll y){
	ll ans = 1;
	for(; y; y >>= 1, x = x * x % mod) if(y & 1) ans = ans * x % mod;
	return ans;
}
inline void getrev(int len){
	for(register int i = 0; i < len; ++i){
		rev[i] =  rev[i >> 1] >> 1;
		if(i & 1)rev[i] |= len >> 1;
	}
}
inline void ntt(ll a[], int len){
	for(int i = 1; i < len; ++i)if(i < rev[i]) swap(a[i], a[rev[i]]);
	for(int l = 2; l <= len; l <<= 1){
		ll wn = qpow(3, (mod - 1) / l), p = l >> 1;
		for(int j = 0; j < len; j += l){
			ll w = 1;
			for(int k = j; k < j + p; ++k){
				ll x = a[k], y = w * a[k + p] % mod;
				a[k] = (x + y) % mod; a[k + p] = (x - y + mod) % mod;
				w = w * wn % mod; 
			}
		}
	}
}
inline void intt(ll a[], int len){
	ntt(a, len); reverse(a + 1, a + len);
	int inv = qpow(len, mod - 2);
	for(int i = 0; i < len; ++i)a[i] = a[i] * inv % mod;
}

vector 封装 多项式 加 减 乘 除 模 求逆 开方 对数 指数

poly
int qpow(int x, int y){
	int ans = 1;
	for(; y; y >>= 1, x = 1ll * x * x % mod)if(y & 1)ans = 1ll * ans * x % mod;
	return ans;
}
void add(int &x, int y){x += y; if(x >= mod)x -= mod;}
int rev[maxn], deg, wn[maxn];
void init(int len){
	deg = 1; while(deg < len)deg <<= 1;
	wn[0] = 1; wn[1] = qpow(3, (mod - 1) / deg); 
	for(int i = 1; i < deg; ++i){
		rev[i] = (rev[i >> 1] >> 1);
		if(i & 1)rev[i] |= (deg >> 1);
		wn[i] = 1ll * wn[i - 1] * wn[1] % mod;
	}
}

struct poly{
	vector<int>f;
	int &operator [](const int &i){return f[i];}
	int operator [](const int &i)const{return f[i];}
	void set(int n){f.resize(n);}
	int si(){return f.size();}
	int si()const{return f.size();}
	void adj(){while(f.size() && f.back() == 0)f.pop_back();}
	poly operator << (const int &x){poly ans; ans.set(x); for(int v : f)ans.f.push_back(v); return ans;}
	poly operator >> (const int &x){poly ans; for(int i = x; i < si(); ++i)ans.f.push_back(f[i]); return ans;}
	void ntt(){
		for(int i = 1; i < deg; ++i)if(i < rev[i])swap(f[i], f[rev[i]]);
		for(int l = 2, hl = 1; l <= deg; l <<= 1, hl <<= 1){
			for(int i = 0; i < deg; i += l){
				for(int j = i, x, y; j < i + hl; ++j){
					x = f[j], y = 1ll * wn[deg / l * (j - i)] * f[j + hl] % mod;
					f[j] = (x + y) % mod; f[j + hl] = (x - y + mod) % mod;
				}
			}
		}
	}
	void intt(){
		ntt(); reverse(f.begin() + 1, f.end()); int Inv = qpow(deg, mod - 2);
		for(int i = 0; i < deg; ++i)f[i] = 1ll * f[i] * Inv % mod;
	}
	friend poly operator + (poly x, const poly &y){
		x.set(max(x.si(), y.si()));
		for(int i = 0; i < y.si(); ++i)add(x[i], y[i]);
		return x;
	}
	void operator += (const poly &x){
		set(max(x.si(), si()));
		for(int i = 0; i < x.si(); ++i)add(f[i], x[i]);
	}
	friend poly operator - (poly x, const poly &y){
		x.set(max(x.si(), y.si()));
		for(int i = 0; i < y.si(); ++i)add(x[i], mod - y[i]);
		return x;
	}
	void operator -= (const poly x){
		set(max(x.si(), si()));
		for(int i = 0; i < x.si(); ++i)add(f[i], mod - x[i]);
	}
	friend poly operator * (poly x, poly y){
		poly ans; init(x.si() + y.si() - 1);
		x.set(deg); y.set(deg); ans.set(deg); x.ntt(); y.ntt();
		for(int i = 0; i < deg; ++i)ans[i] = 1ll * x[i] * y[i] % mod;
		ans.intt(); ans.adj(); return ans;
	}
	void operator *= (poly x){
		init(x.si() + si() - 1); x.set(deg); set(deg); x.ntt(); ntt();
		for(int i = 0; i < deg; ++i)f[i] = 1ll * f[i] * x[i] % mod;
		intt(); adj();
	}
	void reve(){reverse(f.begin(), f.end());}
	friend poly operator / (poly x, poly y){
		int s = x.si() - y.si() + 1;
		x.reve(); y.reve(); y.set(s);
		y = y.inv(); y *= x; y.set(s);
		y.reve(); return y;
	}
	friend pair<poly, poly> operator % (poly x, poly y){
		poly z = x / y; 
		poly r = x - y * z;
		r.set(y.si() - 1);
		return {z, r};
	}
	poly inv(){
		poly ans; ans.set(1); ans[0] = qpow(f[0], mod - 2); poly a, b;
		for(int len = 2; len < si() + si(); len <<= 1){
			a.set(min(si(), len)); b = ans;
			for(int i = 0; i < a.si(); ++i)a[i] = f[i];
			init(a.si() + a.si() - 1); a.set(deg); b.set(deg); ans.set(deg);
			a.ntt(); b.ntt(); 
			for(int i = 0; i < deg; ++i)ans[i] = (2 - 1ll * a[i] * b[i] % mod + mod) % mod * b[i] % mod;
			ans.intt(); ans.set(len);
		}
		ans.set(si()); return ans;
	}
	poly sqrt(){
		poly ans, a; ans.set(1); ans[0] = 1; int inv2 = (mod + 1) >> 1;
		for(int len = 2; len < si() + si(); len <<= 1){
			int nl = min(len, si()); ans.set(len); a.set(nl);
			for(int i = 0; i < nl; ++i)a[i] = f[i]; a *= ans.inv();
			for(int i = 0; i < nl; ++i)ans[i] = 1ll * (ans[i] + a[i]) * inv2 % mod;
		}
		ans.set(si()); return ans;
	}
	void der(){for(int i = 1; i < f.size(); ++i)f[i - 1] = 1ll * f[i] * i % mod; f.back() = 0;}
	poly Der(){poly g; g.f = f; g.der(); return g;}
	void inte(){for(int i = f.size() - 1; i > 0; --i)f[i] = 1ll * f[i - 1] * qpow(i, mod - 2) % mod; f[0] = 0;}
	poly Inte(){poly g; g.f = f; g.inte(); return g;}
	poly ln(){
		poly ans = inv(); ans *= (*this).Der(); 
		ans.inte(); ans.set(si()); return ans;
	}
	poly exp(){
		poly ans, a, b; ans.set(1); ans[0] = 1;
		for(int len = 2; len < si() + si(); len <<= 1){
			ans.set(len); a = ans.ln();
			b.set(min(si(), len));
			for(int i = 0; i < b.si(); ++i)b[i] = f[i];
			b -= a; ++b[0]; ans *= b; ans.set(len);
		}
		ans.set(si()); return ans;
	}
	poly pow(int n){
		poly ans; ans = ln();
		for(int i = 0; i < si(); ++i)ans[i] = 1ll * ans[i] * n % mod;
		return ans.exp();
	}
};

树形结构

左偏树
#include<cstring>
#include<algorithm>
#include<queue>
#include<iostream>
#include<cmath>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
int read(){
	int x = 0; char c = getchar();
	while(!isdigit(c))c = getchar();
	do{x = x * 10 + (c ^ 48); c = getchar();}while(isdigit(c));
	return x;
}
const int maxn = 100005;
int n, m;
int son[maxn][2], dis[maxn], f[maxn];
bool del[maxn];
struct node{
	int id, val;
	friend bool operator < (const node &x, const node &y){
		return x.val == y.val ? x.id < y.id : x.val < y.val;
	}
}d[maxn];
int fa(int x){return f[x] == x ? x : f[x] = fa(f[x]);}
int merge(int x, int y){
	if(!x || !y)return x | y;
	if(d[y] < d[x])swap(x, y);
	son[x][1] = merge(son[x][1], y);
	if(dis[son[x][1]] > dis[son[x][0]])swap(son[x][1], son[x][0]);
	dis[x] = dis[son[x][1]] + 1;
	return x;
}
int main(){
	n = read(), m = read();
	for(int i = 1; i <= n; ++i)d[i].val = read(), d[i].id = i, f[i] = i;
	for(int op = 1; op <= m; ++op){
		int opt, x;
		opt = read(), x = read();
		if(opt & 1){
			int y = read();
			if(del[x] || del[y])continue;
			x = fa(x); y = fa(y);
			if(x == y)continue;
			f[x] = f[y] = merge(x, y);
		}else{
			if(del[x]){
				printf("-1\n"); continue;
			}
			x = fa(x);
			printf("%d\n",d[x].val);
			del[x] = 1;
			f[son[x][0]] = f[son[x][1]] = f[x] = merge(son[x][0], son[x][1]);
			son[x][0] = son[x][1] = dis[x] = 0;
		}
	}
	return 0;
}
splay
struct splay_tree{
	#define ls t[x].son[0]
	#define rs t[x].son[1]
	#define son(x) (t[t[x].fa].son[1]==x)
	struct node{
		int son[2],fa,size,val,cnt;
	}t[maxn];
	int tot,root;
	int New(int val,int fa){t[++tot].val=val;t[tot].cnt=t[tot].size=1;t[tot].fa=fa;return tot;}
	void push_up(int x){t[x].size=t[ls].size+t[rs].size+t[x].cnt;}
	void rotate(int x){
		int f=t[x].fa,ff=t[f].fa,s=son(x),ss=son(f);
		t[f].son[s]=t[x].son[s^1];
		t[t[x].son[s^1]].fa=t[x].son[s^1]?f:0;
		t[x].son[s^1]=f;t[f].fa=x;t[x].fa=ff;
		t[ff].son[ss]=ff?x:0;
		push_up(f);push_up(x);
	}
	void splay(int x){
		for(int f=t[x].fa;f=t[x].fa;rotate(x))
		  if(t[f].fa)rotate(son(x)==son(f)?f:x);
		root=x;
	}
	void insert(int val){
		if(!root)return root=New(val,0),void();
		int x=root;
		while(1){
			if(t[x].val==val)return ++t[x].cnt,push_up(x),splay(x),void();
			int y=x;x=t[y].son[val>t[y].val];
			if(!x)return t[y].son[val>t[y].val]=New(val,y),push_up(y),splay(tot),void();
		}
	}
	int kth(int th){
		int x=root; 
		while (1){
			if(t[ls].size<th&&t[ls].size+t[x].cnt>=th)return splay(x),t[x].val;
			if(th<=t[ls].size)x=ls;
			else th-=t[ls].size+t[x].cnt,x=rs;
		}
	}
	void erase(int val){
		insert(val);
		if(t[root].cnt>2)return t[root].cnt-=2,push_up(root),void();
		int x=root;int sl=ls,sr=rs;
		ls=rs=t[ls].fa=t[rs].fa=0;
		if(!sl||!sr)return root=sl|sr,void();
		else root=sl,kth(t[sl].size),t[root].son[1]=sr,t[sr].fa=root,push_up(root);
	}
	int rank(int val){insert(val);int ans=t[t[root].son[0]].size+1;erase(val);return ans;}
	int pre(int val){insert(val);int ans=kth(t[t[root].son[0]].size);erase(val);return ans;}
	int nxt(int val){insert(val);int ans=kth(t[t[root].son[0]].size+t[root].cnt+1);erase(val);return ans;}
}T;
LCT
struct LCT{
	#define son(x) (x == t[t[x].fa].son[1])
	#define lson t[x].son[0]
	#define rson t[x].son[1]
	struct node{
		int son[2], fa, size, val, sum,  lazy;
	}t[maxn];
	int cnt;
	int isroot(int x){return t[t[x].fa].son[0] != x && t[t[x].fa].son[1] != x;}
	int newnode(int val, int fa){
		++cnt;
		t[cnt].size = 1;
		t[cnt].fa = fa;
		t[cnt].val = val;
		t[cnt].sum = val;
		return cnt;
	}
	void push_up(int x){
		t[x].size = t[lson].size + t[rson].size + 1;
		t[x].sum = t[lson].sum ^ t[rson].sum ^ t[x].val;
	}
	void push_down(int x){
		if(!t[x].lazy)return;
		swap(t[lson].son[0], t[lson].son[1]);
		swap(t[rson].son[0], t[rson].son[1]);
		t[lson].lazy ^= 1; t[rson].lazy ^= 1; t[x].lazy ^= 1;
	}
	void spread(int x){
		if(!isroot(x))spread(t[x].fa);
		push_down(x);
	}
	void rotate(int x){
		int f = t[x].fa, ff = t[f].fa, s = son(x), ss = son(f);
		if(!isroot(f))t[ff].son[ss] = x;
		t[f].son[s] = t[x].son[s ^ 1];
		t[t[x].son[s ^ 1]].fa = t[x].son[s ^ 1] ? f : 0;
		t[x].son[s ^ 1] = f;
		t[f].fa = x;
		t[x].fa = ff;
		push_up(f);
		push_up(x);
	}
	void splay(int x){
		spread(x);
		for(int f = t[x].fa; !isroot(x); rotate(x) , f = t[x].fa)
		  if(!isroot(f))rotate(son(f) == son(x) ? f : x);
	}
	int access(int x){
		int p;
		for(p = 0; x; p = x, x = t[x].fa){
			splay(x); rson = p, push_up(x);
		}
		return p;
	}
	void makeroot(int x){
		x = access(x);
		swap(lson, rson);
		t[x].lazy ^= 1;
	}
	int findroot(int x){
		access(x);
		splay(x);
		push_down(x);
		while(lson)x = lson, push_down(x);
		splay(x);
		return x;
	}
	void link(int x, int y){
		if(findroot(x) == findroot(y))return;
		makeroot(x);
		splay(x);
		t[x].fa = y;
	}
	void split(int x, int y){
		makeroot(x);
		access(y);
		splay(y);
	}
	void cut(int x, int y){
		split(x, y);
		if(t[y].son[0] != x)return;
		t[x].fa = t[y].son[0] = 0; push_up(y);
	}
}T;
FHQ
struct FHQ_Treap{
	struct node{
		int l,r,size,val,key;
	}t[maxn];
	int tot,root;
	int New(int x){t[++tot].val=x;t[tot].key=rand();t[tot].size=1;return tot;}
	void push_up(int x){t[x].size=t[t[x].l].size+t[t[x].r].size+1;}
	void split(int x,int &rtx,int &rty,int val){
		if(x==0)return rtx=rty=0,void();
		if(val<t[x].val){split(t[x].l,rtx,t[x].l,val);rty=x;push_up(rty);return;}
		else{split(t[x].r,t[x].r,rty,val);rtx=x;push_up(rtx);return;}
	}
	int merge(int x,int y){
		if(!x||!y)return x|y;
		if(t[x].key<t[y].key){t[x].r=merge(t[x].r,y);push_up(x);return x;}
		else{t[y].l=merge(x,t[y].l);push_up(y);return y;}
	}
	void insert(int x){
		int l=0,r=0;split(root,l,r,x);
		root=merge(merge(l,New(x)),r);
	}
	void erase(int x){
		int l,m,r;split(root,l,r,x);split(l,l,m,x-1);
		m=merge(t[m].l,t[m].r);
		root=merge(merge(l,m),r);
	}
	int kth(int x,int id){
		if(t[t[x].l].size+1==id)return t[x].val;
		if(t[t[x].l].size>=id)return kth(t[x].l,id);
		return kth(t[x].r,id-t[t[x].l].size-1);
	}
	int rank(int x){
		int l=0,r=0,ans=0;
		split(root,l,r,x-1);
		ans=t[l].size+1;
		root=merge(l,r);
		return ans;
	}
	int pre(int x){
		int l=0,r=0,ans=0;
		split(root,l,r,x-1);
		ans=kth(l,t[l].size);
		root=merge(l,r);
		return ans;
	}
	int nxt(int x){
		int l=0,r=0,ans=0;
		split(root,l,r,x);
		ans=kth(r,1);
		root=merge(l,r);
		return ans;
	}
}T;

Treap
struct Treap{
	struct node{
		int l,r,val,key,siz,cnt;
	}t[maxn];
	int tot,root;

	int New(int x){
		t[++tot].val=x;
		t[tot].key=rand();
		t[tot].siz=t[tot].cnt=1;
		return tot;
	}

	void push_up(int x){t[x].siz=t[t[x].l].siz+t[t[x].r].siz+t[x].cnt;}

	void zig(int &x){
		int y=t[x].l;
		t[x].l=t[y].r;
		t[y].r=x;
		x=y;
		push_up(t[x].r);
		push_up(x);
	}

	void zag(int &x){
		int y=t[x].r;
		t[x].r=t[y].l;
		t[y].l=x;
		x=y;
		push_up(t[x].l);
		push_up(x);
	}

	void insert(int &x,int val){
		if(x==0)return x=New(val),void();
		if(t[x].val==val)return ++t[x].cnt,++t[x].siz,void();
		if(val<t[x].val){
			insert(t[x].l,val);
			push_up(x);
			if(t[x].key<t[t[x].l].key)return zig(x);
		}
		if(val>t[x].val){
			insert(t[x].r,val);
			push_up(x);
			if(t[x].key<t[t[x].r].key)return zag(x);
		}
	}

	void erase(int &x,int val){
		if(x==0)return;
		if(t[x].val==val){
			if(t[x].cnt>1)return --t[x].cnt,--t[x].siz,void();
			if(!t[x].l&&!t[x].r)return x=0,void();
			if(!t[x].r||t[t[x].l].key>t[t[x].r].key)return zig(x),erase(t[x].r,val),push_up(x);
			if(!t[x].l||t[t[x].l].key<t[t[x].r].key)return zag(x),erase(t[x].l,val),push_up(x);
		}
		if(val<t[x].val)erase(t[x].l,val);
		else erase(t[x].r,val);
		push_up(x);
	}

	int rank(int x,int val){
		if(x==0)return 0;
		if(t[x].val==val)return t[t[x].l].siz;
		if(t[x].val<val)return rank(t[x].r,val)+t[t[x].l].siz+t[x].cnt;
		else return rank(t[x].l,val);
	}

	int pre(int val){
		int x=root,ans=-2147483645;
		while(x){
			if(t[x].val<val)ans=max(ans,t[x].val),x=t[x].r;
			else x=t[x].l;
		}
		return ans;
	}

	int next(int val){
		int x=root,ans=2147483647;
		while(x){
			if(t[x].val>val)ans=min(ans,t[x].val),x=t[x].l;
			else x=t[x].r;
		}
		return ans;
	}

	int kth(int x,int th){
		if(th<=t[t[x].l].siz)return kth(t[x].l,th);
		if(th<=t[t[x].l].siz+t[x].cnt)return t[x].val;
		return kth(t[x].r,th-t[t[x].l].siz-t[x].cnt);
	}

	void print(int x){
		if(t[x].l)print(t[x].l);
		printf("%d ",t[x].val);
		if(t[x].r)print(t[x].r);
	}
}T;
笛卡尔树
	for(int i = 1; i <= n; ++i){
		int k = top;
		while(k && a[st[k]] < a[i])--k;
		if(k)rs[st[k]] = i;
		if(k < top)ls[i] = st[k + 1];
		st[++k] = i; top = k;
	}

图论

支配树
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

int read(){
	int x = 0; char c = getchar();
	while(!isdigit(c))c = getchar();
	do{x = x * 10 + (c ^ 48); c = getchar();}while(isdigit(c));
	return x;
}
const int maxn = 3e5 + 55, inf = 0x3f3f3f3f;
int n, m, ans[maxn], zp[maxn], bzp[maxn];
vector<int>g1[maxn], g2[maxn], t[maxn];
int fa[maxn], dfn[maxn], id[maxn], tim;
struct DSU{
	int f[maxn], val[maxn];
	void init(){for(int i = 1; i <= n; ++i)f[i] = val[i] = i;}
	int fa(int x){
		if(f[x] == x)return x;
		int nf = fa(f[x]);
		if(dfn[bzp[val[f[x]]]] < dfn[bzp[val[x]]])val[x] = val[f[x]];
		return f[x] = nf;
	}
	void merge(int x, int fx){f[x] = fx;}
	int query(int x){fa(x); return val[x];}
}s;
void dfs(int x){
	id[dfn[x] = ++tim] = x;
	for(int v : g1[x])if(!dfn[v])fa[v] = x, dfs(v);
}
void solve(){
	dfs(1); s.init(); 
	for(int i = 1; i <= n; ++i)bzp[i] = zp[i] = i;
	for(int i = n; i >= 1; --i){
		int now = id[i];
		for(int v : t[now]){
			int tmp = s.query(v);
			zp[v] = now == bzp[tmp] ? now : tmp;
		}
		for(int v : g2[now]){
			if(!dfn[v])continue;
			int tmp = s.query(v);
			if(dfn[bzp[tmp]] < dfn[bzp[now]])bzp[now] = bzp[tmp];
		}
		t[bzp[now]].push_back(now);
		t[now].clear();
		s.merge(now, fa[now]);
	}
	for(int i = 2; i <= n; ++i){
		int now = id[i];
		if(zp[now] != bzp[now])zp[now] = zp[zp[now]];
	}
}

int main(){
	n = read(), m = read();
	for(int i = 1; i <= m; ++i){
		int u = read(), v = read();
		g1[u].push_back(v);
		g2[v].push_back(u);
	}
	solve();
	for(int i = n; i >= 2; --i)ans[zp[id[i]]] += ++ans[id[i]];
	++ans[1];
	for(int i = 1; i <= n; ++i)printf("%d ",ans[i]); printf("\n");
	return 0;
}
dinic
typedef long long ll;

const ll inf = 1e15;
const int maxn = 205;
const int maxm = 10005;
int n, m;

struct WWL{
	int s, t;
	int head[maxn], tot = 1;
	struct edge{int to, net; ll val;}e[maxm];
	void add(int u, int v, int w){
		e[++tot].net = head[u];
		head[u] = tot;
		e[tot].to = v;
		e[tot].val = w;
	}
	void link(int u, int v, int w){add(u, v, w); add(v, u, 0);}
	int dep[maxn], now[maxn];
	bool bfs(){
		memset(dep, 0, sizeof(dep));
		queue<int>q; dep[s] = 1; q.push(s);
		now[s] = head[s];
		while(!q.empty()){
			int x = q.front(); q.pop();
			for(int i = head[x]; i; i = e[i].net){
				int v = e[i].to;
				if(e[i].val > 0 && dep[v] == 0){
					dep[v] = dep[x] + 1;
					now[v] = head[v];
					if(v == t)return true;
					q.push(v);
				}
			}
		}
		return false;
	}
	ll dfs(int x, ll from){
		if(x == t || from <= 0)return from;
		ll res = from; int i;
		for(i = now[x]; i; i = e[i].net){
			int v = e[i].to;
			if(e[i].val > 0 && dep[v] == dep[x] + 1){
				ll k = dfs(v, min(res, e[i].val));
				if(k <= 0)dep[v] = 0;
				e[i].val -= k;
				e[i ^ 1].val += k;
				res -= k;
				if(res <= 0)break;
			}
		}
		now[x] = i;
		return from - res;
	}
	ll dinic(){
		ll ans = 0;
		while(bfs())ans += dfs(s, inf);
		return ans;
	}
	void init(){
		scanf("%d%d%d%d",&n,&m,&s,&t);
		for(int i = 1; i <= m; ++i){
			int u, v, w; scanf("%d%d%d",&u,&v,&w);
			link(u, v, w);
		}
		printf("%lld\n",dinic());
	}
}w;

mcmf
struct MCMF{
	int s, t;
	int head[maxn], tot = 1;
	struct edge{int to, net; ll val, cost;}e[maxm];
	void add(int u, int v, int w, int c){
		e[++tot] = {v, head[u], w, c};
		head[u] = tot;
	}
	void link(int u, int v, int w, int c){add(u, v, w, c); add(v, u, 0, -c);}
	bool vis[maxn]; queue<int>q; ll dis[maxn];
	bool spfa(){
		for(int i = 1; i <= n; ++i)dis[i] = inf, vis[i] = false;
		vis[s] = true; dis[s] = 0; q.push(s);
		while(!q.empty()){
			int x = q.front(); q.pop();
			vis[x] = false;
			for(int i = head[x]; i; i = e[i].net){
				int v = e[i].to;
				if(e[i].val > 0 && dis[v] > dis[x] + e[i].cost){
					dis[v] = dis[x] + e[i].cost;
					if(!vis[v])q.push(v), vis[v] = true;
				}
			}
		}
		return dis[t] != inf;
	}
	ll dfs(int x, ll from){
		if(x == t || from <= 0)return from;
		vis[x] = true; ll res = from;
		for(int i = head[x]; i; i = e[i].net){
			int v = e[i].to;
			if(!vis[v] && e[i].val > 0 && dis[v] == dis[x] + e[i].cost){
				ll k = dfs(v, min(res, e[i].val));
				e[i].val -= k;
				e[i ^ 1].val += k;
				res -= k;
				if(res <= 0)break;
			}
		}		
		return from - res;
	}
	ll flow, cost;
	void mcmf(){
		while(spfa()){
			ll k = dfs(s, inf);
			flow += k; cost += k * dis[t];
		}
	}
	void init(){
		n = read(), m = read(), s = read(), t = read();
		for(int i = 1; i <= m; ++i){
			int u = read(), v = read(), w = read(), c = read();
			link(u, v, w, c);
		}
		mcmf();
		printf("%lld %lld\n",flow, cost);
	}
}w;

斯坦纳树
typedef pair<int, int> pii;
priority_queue<pii, vector<pii>, greater<pii>>q;
int dp[maxn][1025];
bool vis[maxn];
void dij(int s){
	memset(vis, 0, sizeof(vis));
	while(!q.empty()){
		int x = q.top().second;
		q.pop();
		if(vis[x])continue;
		vis[x] = 1;
		for(int i = head[x]; i; i = e[i].net){
			int v = e[i].to;
			if(dp[v][s] > dp[x][s] + e[i].val){
				dp[v][s] = dp[x][s] + e[i].val;
				q.push(pii(dp[v][s], v));
			}
		}
	}
}
int main(){
	n = read(), m = read(), k = read();
	for(int  i = 1; i <= m; ++i){
		int u = read(), v = read(), w = read();
		add(u, v, w); add(v, u ,w);
	}
	for(int i = 1; i <= k; ++i)ts[i] = read();
	memset(dp, 0x3f, sizeof(dp));
	for(int i = 1; i <= k; ++i)dp[ts[i]][1 << (i - 1)] = 0;
	for(int s = 1; s < (1 << k); ++s){
		for(int i = 1; i <= n; ++i){
			for(int x = s & (s - 1); x; x = s & (x - 1))
				dp[i][s] = min(dp[i][s], dp[i][x] + dp[i][s xor x]);
			if(dp[i][s] != dp[0][0]){q.push(pii(dp[i][s], i));}
		}
		dij(s);
	}
	printf("%d\n",dp[ts[1]][(1 << k) - 1]);
	return 0;
}
2-sat
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
int read(){
	int x = 0; char c = getchar();
	while(!isdigit(c))c = getchar();
	do{x = x * 10 + (c ^ 48); c = getchar();}while(isdigit(c));
	return x;
}
const int maxn = 2e6 + 55;
int n, m;
vector<int>g[maxn];
int dfn[maxn], low[maxn], tim, st[maxn], top, bl[maxn], cnt;
bool vis[maxn];
void tarjan(int x){
	dfn[x] = low[x] = ++tim; vis[x] = true; st[++top] = x;
	for(int v : g[x])
		if(!dfn[v])tarjan(v), low[x] = min(low[x], low[v]);
		else if(vis[v])low[x] = min(low[x], dfn[v]);
	if(low[x] == dfn[x]){
		bl[x] = ++cnt;
		while(st[top] != x)bl[st[top]] = cnt, vis[st[top--]] = false;
		vis[x] = false; --top;
	}
}
int main(){
	n = read(), m = read();
	for(int i = 1; i <= m; ++i){
		int u = read(), a = read(), v = read(), b = read();
		g[u + (!a) * n].push_back(v + b * n);
		g[v + (!b) * n].push_back(u + a * n);
	}
	for(int i = 1; i <= (n << 1); ++i)if(!dfn[i])tarjan(i);
	for(int i = 1; i <= n; ++i)if(bl[i] == bl[i + n]){printf("IMPOSSIBLE\n"); return 0;}
	printf("POSSIBLE\n");
	for(int i = 1; i <= n; ++i)printf("%d ",bl[i + n] < bl[i]);
	return 0;
}

字符串

pam
#include<cstring>
#include<iostream>
using namespace std;
const int maxn = 5e5+55;
char s[maxn];
int ch[maxn][27], len[maxn], fail[maxn], dep[maxn];
int main(){
	cin >> s + 1;
	s[0] = '#';
	int n = strlen(s + 1);
	int las = 0, ans = 0, cnt = 1;
	fail[0] = 1;len[1] = -1;
	for(int i = 1 ; i <= n; ++i){
		while(s[i - len[las] - 1] != s[i])las = fail[las];
		if(!ch[las][s[i] - 'a']){
			len[++cnt] = len[las] + 2;
			int j = fail[las];
			while(s[i - len[j] - 1] != s[i])j = fail[j];
			fail[cnt] = ch[j][s[i] - 'a'];
			ch[las][s[i] - 'a'] = cnt;
		}
		las = ch[las][s[i] - 'a'];
		cout << (ans = dep[las]) << " " ;
	}
	return 0;
}

sa
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f;
const int maxn=1000005;
char s[maxn];
int n,w,sa[maxn],rk[maxn<<1|1],id[maxn],m=300,oldrk[maxn<<1|1],cnt[maxn],px[maxn];
bool cmp(int x,int y,int w){
	return oldrk[x]==oldrk[y]&&oldrk[x+w]==oldrk[y+w];
}
void get_ht() {
	for(int k=0,i=1;i<=n;++i){
		if(rk[i]==1)continue;
		if(k)--k;
		while(s[i+k]==s[sa[rk[i]-1]+k])++k;
		ht[rk[i]]=k;
	}
}
int main(){
	scanf("%s",s+1);
	n=strlen(s+1);
	for(int i=1;i<=n;++i)++cnt[rk[i]=s[i]];//按照第一个字母排个序,这个时候只需要相对大小关系,里面的东西暂时不太合法
	for(int i=1;i<=m;++i)cnt[i]+=cnt[i-1];//桶累加
	for(int i=n;i>=1;--i)sa[cnt[rk[i]]--]=i;//cnt[..]为i的新rank 其实是sa[rk[i]]=i
	m=max(m,n);//m为桶的值域

	for(w=1;w<n;w<<=1){
		int p=0;
		for(int i=n;i>n-w;--i)id[++p]=i;//空串直接记录,按照第二关键字他们最小且没有顺序,所以随便给个顺序即可
		for(int i=1;i<=n;++i)if(sa[i]>w)id[++p]=sa[i]-w;//第二关键字,用后缀i的当前sa的顺序去更新后缀sa[i]-w

		for(int i=1;i<=m;++i)cnt[i]=0;//清桶
		for(int i=1;i<=n;++i)++cnt[px[i]=rk[id[i]]];//按照原来的rank排序,px临时存一下rk[id[i]],减少不必要的内存访问
		for(int i=1;i<=m;++i)cnt[i]+=cnt[i-1];//累加
		for(int i=n;i>=1;--i)sa[cnt[px[i]]--]=id[i];//cnt[..]为sa[i]的新rank 而为了避免改乱,所以原来的sa用id来代替,这就是上面和这里赋值用id的原因
		
		for(int i=1;i<=n;++i)oldrk[i]=rk[i];//copy一下,cmp用
		p=0;
		for(int i=1;i<=n;++i)rk[sa[i]]=cmp(sa[i],sa[i-1],w)?p:++p;//写cmp减少不必要的内存访问,去重

		if(p==n)break;//已经排完就不用管了
		m=p;//值域优化
	}
	for(int i=1;i<=n;++i)printf("%d ",sa[i]);
	return 0;
}

sam
struct SAM{
	int cnt = 1, las = 1;
	void add(int c){
		int fa = las, now = las = ++cnt;
		d[now].len = d[fa].len + 1;
		f[now] = 1;
		for(; fa && !d[fa].ch[c]; fa = d[fa].fa) d[fa].ch[c] = now;
		if(!fa)d[now].fa = 1;
		else{
			int j = d[fa].ch[c];
			if(d[j].len == d[fa].len + 1)d[now].fa = j;
			else{
				int clone = ++cnt;
				d[clone] = d[j];
				d[clone].len = d[fa].len + 1;
				d[j].fa = d[now].fa = clone;
				for(; fa && d[fa].ch[c] == j; fa = d[fa].fa)d[fa].ch[c] = clone;
			}
		}
	}
}S;


general-sam
#include<iostream>
#include<cstring>

using namespace std;

const int maxn = 15e5 + 55;

char c[maxn];
struct node{
    int len, fa, ch[26];
}d[maxn];

struct SAM{
    int cnt = 1, las = 1;
    void add(int c){
        if(d[las].ch[c]){
            int fa = las, x = d[las].ch[c];
            if(d[fa].len + 1 == d[x].len)las = x;
            else{
                int now = las = ++cnt;
                d[now] = d[x];
                d[now].len = d[fa].len + 1;
                for(; fa && d[fa].ch[c] == x; fa = d[fa].fa)d[fa].ch[c] = now;
                d[x].fa = now;
            }
        }else{    
            int fa = las;
            int now = las = ++cnt;
            d[now].len = d[fa].len + 1;
            for(; fa && !d[fa].ch[c]; fa = d[fa].fa)d[fa].ch[c] = now;
            if(!fa)d[now].fa = 1;
            else{
                int x = d[fa].ch[c];
                if(d[fa].len + 1 == d[x].len)d[now].fa = x;
                else{
                    int clone = ++cnt;
                    d[clone] = d[x];
                    d[clone].len = d[fa].len + 1;
                    d[x].fa = d[now].fa = clone;
                    for(; fa && d[fa].ch[c] == x; fa = d[fa].fa)d[fa].ch[c] = clone;
                }
            }
        }
    }
}S;
int n;
int main(){
    cin >> n;
    for(int i = 1; i <= n; ++i){
        cin >> c + 1;
        int len = strlen(c + 1);
        S.las = 1;
        for(int i = 1; i <= len ; ++i)S.add(c[i] - 'a');
    }
    return 0;
}

AC
struct AC{
    int root = 1, cnt = 1;
    int ch[maxn][26],fail[maxn],size[maxn];
    void insert(){
        int len = strlen(c + 1), now = root;
        for(int i = 1; i <= len; ++i)s[i] = c[i] - 'a';
        for(int i = 1; i <= len; ++i){
            if(!ch[now][s[i]])ch[now][s[i]] = ++cnt;
            now = ch[now][s[i]];
        }
        ++size[now];
    }
    queue<int>q;
    void built(){
        for(int i = 0; i < 26; ++i)
          if(ch[root][i])fail[ch[root][i]] = root,q.push(ch[root][i]);
          else ch[root][i] = root;
        while(!q.empty()){
            int x = q.front(); q.pop();
            for(int i = 0; i < 26; ++i){
                if(ch[x][i])fail[ch[x][i]] = ch[fail[x]][i], q.push(ch[x][i]);
                else ch[x][i] = ch[fail[x]][i];
            }
        }
    }
    bool vis[maxn];
    int match(){
        int len = strlen(c + 1),now = root;
        for(int i = 1; i <= len; ++i)s[i] = c[i] - 'a';
        int ans = 0;
        for(int i = 1; i <= len; ++i){
            now = ch[now][s[i]];
            if(!vis[now])ans += size[now], vis[now] = 1;
        }
        return ans;
    }
}A;
manacher
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 22000005;
char c[maxn], s[maxn];
int p[maxn];

int main(){
	scanf("%s",c + 1);
	int n = strlen(c + 1), cnt = 0;
	s[++cnt] = '~', s[++cnt] = '#';
	for(int i = 1; i <= n; ++i)s[++cnt] = c[i], s[++cnt] = '#';
	s[++cnt] = '!';
	int mr = 0, mid = 0, ans = 0;
	for(int i = 2; i < cnt; ++i){
		if(i <= mr)p[i] = min(p[mid * 2 - i], mr - i + 1);
		else p[i] = 1;
		while(s[i - p[i]] == s[i + p[i]]) ++p[i];
		if(i + p[i] > mr)mr = i + p[i] - 1, mid = i;
		ans = max(ans, p[i]);
	}
	printf("%d\n",ans - 1);
	return 0;
}
最小表示法
#include<iostream>
#include<cstring>

using namespace std;

const int maxn = 6e5 + 55;
int a[maxn], n;

int main(){
    ios::sync_with_stdio(false);
    cin >> n;
    for(int i = 0; i < n; ++i)cin >> a[i];
    for(int i = 0; i < n; ++i)a[i + n] = a[i];
    int i = 0, j = 1, k = 0;
    while(i < n && j < n && k < n){
        if(a[(i + k) % n] == a[(j + k) % n])++k;
        else{
            if(a[(i + k) % n] > a[(j + k) % n])i = i + k + 1;
            else j = j + k + 1;
            if(i == j)++i;
            k = 0;
        }
    }
    int ans = min(i, j);
    for(int i = 0; i < n; ++i)cout << a[(i + ans) % n] << " ";
    return 0;
}
kmp
	for(int i = 2, j = 0; i <= l2; ++i){
		while(j && s2[j + 1] != s2[i])j = nxt[j];
		if(s2[j + 1] == s2[i]) ++j;
		nxt[i] = j;
	}
	for(int j = 0, i = 1; i <= l1; ++i){
		while(j && s2[j + 1] != s1[i])j = nxt[j];
		if(s2[j + 1] == s1[i]) ++j;
		if(j == l2)printf("%d\n",i - l2 + 1), j = nxt[j];
	}
excmp/z函数
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;

typedef long long ll;
const int maxn = 2e7 + 55;
int nxt[maxn], ext[maxn];
char a[maxn], b[maxn];
void solvenxt(){
	int len = strlen(b);
	int p = 0, k = 1;
	nxt[0] = len; while(p + 1 < len && b[p] == b[p + 1])++p;
	nxt[1] = p;
	for(int i = 2; i < len; ++i){
		p = k + nxt[k] - 1;
		int l = nxt[i - k];
		if(i + l <= p)nxt[i] = l;
		else{
			int j = max(0, p - i + 1);
			while(i + j < len && b[i + j] == b[j]) ++j;
			nxt[i] = j;
			k = i;
		}
	}
}
void exkmp(){
	int la = strlen(a), lb = strlen(b);
	int p = 0, k = 0;
	while(p < la && p < lb && a[p] == b[p])++p;
	ext[0] = p;
	for(int i = 1; i < la; ++i){
		p = k + ext[k] - 1;
		int l = nxt[i - k];
		if(i + l <= p)ext[i] = l;
		else {
			int j = max(0, p - i + 1);
			while(i + j < la && j < lb && a[i + j] == b[j]) ++j;
			ext[i] = j;
			k = i;
		}
	}
}
int main(){
	scanf("%s%s",a,b);
	solvenxt();
	exkmp();
	int l = strlen(b);
	ll ans = 0;
	for(int i = 0; i < l; ++i)ans ^= (i + 1ll) * (nxt[i] + 1);
	printf("%lld\n",ans);
	ans = 0;
	l = strlen(a);
	for(int i = 0; i < l; ++i)ans ^= (i + 1ll) * (ext[i] + 1);
	printf("%lld\n",ans);
	return 0;
}

杂项

同下
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include<random>

using namespace std;
typedef unsigned long long ull;
mt19937 rd((ull)(new char) * (ull) (new char));
const int maxn = 10005;
int n, x[maxn], y[maxn], w[maxn];
double ansx, ansy, las;
double s(int l, int r){
	uniform_real_distribution<>d(l, r);
	return d(rd);
}
double check(double nx, double ny){
	double nans = 0;
	for(int i = 1; i <= n; ++i){
		double dx = x[i] - nx, dy = y[i] - ny;
		nans += sqrt(dx * dx + dy * dy) * w[i];
	}
	if(nans < las)las = nans, ansx = nx, ansy = ny;
	return nans;
}
void sa(){
	double t = 100000, down = 0.99;
	double nx = ansx, ny = ansy;
	while(t > 0.0001){
		double nnx = nx + t * (s(0, 1) * 2 - 1);
		double nny = ny + t * (s(0, 1) * 2 - 1);
		double dt = check(nnx, nny) - check(nx, ny);
		if(exp(-dt / t) > s(0, 1))nx = nnx, ny = nny;
		t *= down;
	}
	for(int i = 1; i <= 10000; ++i){
		double nnx = ansx + t * (s(0, 1) * 2 - 1);
		double nny = ansy + t * (s(0, 1) * 2 - 1);
		check(nnx, nny);
	}
}
int main(){
	scanf("%d",&n);
	for(int i = 1; i <= n; ++i){
		scanf("%d%d%d",&x[i], &y[i], &w[i]);
		ansx += x[i], ansy += y[i];
	}
	ansx /= n, ansy /= n, las = check(ansx, ansy);
	sa();sa();sa();sa();sa();
	printf("%.3lf %.3lf\n",ansx, ansy);
	return 0;
}
sa/模拟退火

int check(){
	int nans = 0;
	for(int i = 1; i <= n; ++i){
		for(int j = 1; j <= 3; ++j){
			nans += abs(pos[i] - pos[f[i][j]]);
		}
	}
	return nans / 2;
}
int s(int l, int r){
	uniform_int_distribution<>d(l, r);
	return d(rd);
}
void sa(){
	double t = 100000, down = 0.99, t0 = 0.000001;
	int x ,y, lans;
	while(t > t0){
		do{
			x = s(1, n);
			y = s(1, n);
		}while(x == y);
		swap(pos[x], pos[y]);
		lans = check();
		if(lans <= dis){
			dis = lans;
		}else if(exp((-lans + dis) / t < (double)s(0, INT_MAX) / INT_MAX))swap(pos[x], pos[y]);
		t *= down;
	}
	return ;
}
posted @   Chen_jr  阅读(55)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示