Loading

我的模板

常用

chkmin,chkmax

template<typename T>
bool chkmin(T& x,const T& y){return y<x?(x=y,1):0;}
template<typename T>
bool chkmax(T& x,const T& y){return x<y?(x=y,1):0;}

I/O

getchar 快读

目前看来已经成了时代的眼泪。

template<typename T>
void read(T &x){
	x=0;
	int f=1;
	char ch=getchar();
	while(!isdigit(ch)) f=(ch=='-'?-1:f),ch=getchar();
	while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
	x*=f;
}
template<typename T,typename... Args>
void read(T &x,Args& ...others){
	read(x);
	read(others...);
}

数学

快速幂

ll power(ll x,ll y,ll mod){
	ll r=1;
	for(;y;y>>=1,x=x*x%mod){
		if(y&1) r=r*x%mod;
	}
	return r;
}
ll power(ll x,ll y){
	ll r=1;
	for(;y;y>>=1,x=x*x%Mod){
		if(y&1) r=r*x%Mod;
	}
	return r;
}

扩展欧几里得

void exgcd(ll a,ll b,ll& x,ll& y){
	if(!b){
		x=1,y=0;
		return;
	}
	exgcd(b,a%b,y,x);
	y-=a/b*x;
}

光速幂

struct FastPower{
	const int Size,Base,Mod;
	ll *pow1,*pow2;
	FastPower(ll base,ll lim,int mod):Size(sqrt(lim)+1),Base(base%mod),Mod(mod),pow1(new ll[Size]),pow2(new ll[Size]){
		pow1[0]=pow2[0]=1;
		For(i,1,Size-1) pow1[i]=pow1[i-1]*Base%Mod;
		ll temp=pow1[Size-1]*Base%Mod;
		For(i,1,Size-1) pow2[i]=pow2[i-1]*temp%Mod;
	}
	ll operator()(ll p){return pow1[p%Size]*pow2[p/Size]%Mod;}
	~FastPower(){delete[] pow1;delete[] pow2;}
};

分解质因数

vector<pair<ll,int>> prime_factors(ll x){
	vector<pair<ll,int>> res;
	auto _add=[&](int i){
		if(x%i==0){
			res.emplace_back(i,0);
			while(x%i==0) ++res.back().second,x/=i;
		}
	};
	_add(2),_add(3);
	for(int i=5;1LL*i*i<=x;i+=6) _add(i),_add(i+2);
	if(x>1) res.emplace_back(x,1);
	return res;
}

多项式

namespace polynomial {
	const int N = 5e5 + 5, g = 3;
	int lim, lg2[N], rev[N], pwg[N];
	inline int getsz(int n) { return 1 << (lg2[n - 1] + 1); }
	[[gnu::constructor]] void init() {
		for (int i = 2; i < N; ++i) lg2[i] = lg2[i >> 1] + 1;
		for (int h = 2; h <= N; h <<= 1) {
			int gn = Pow(g, (Mod - 1) / h);
			pwg[h >> 1] = 1;
			for (int i = (h >> 1) + 1; i < h; ++i) pwg[i] = 1LL * pwg[i - 1] * gn % Mod;
		}
	}
	void getrev(int n) {
		if (n == lim) return;
		for (int i = 1; i < (lim = n); ++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) ? n >> 1 : 0);
	}
	void ntt(vector<int>& f, int tp) {
		int n = f.size();
		getrev(n);
		for (int i = 0; i < n; ++i)
			if (i < rev[i])
				swap(f[i], f[rev[i]]);
		for (int h = 2; h <= n; h <<= 1)
			for (int i = 0, p = h >> 1; i < n; i += h)
				for (int j = i; j < i + p; ++j) {
					int t = 1LL * f[j + p] * pwg[j - i + p] % Mod;
					f[j + p] = (f[j] - t + Mod) % Mod, (f[j] += t) %= Mod;
				}
		if (tp == -1) {
			int inv = Pow(n, Mod - 2);
			reverse(f.begin() + 1, f.end());
			for (int i = 0; i < n; ++i) f[i] = 1LL * f[i] * inv % Mod;
		}
	}
	struct poly {
		vector<int> a;
		poly() = default;
		poly(int deg): a(deg + 1, 0) {}
		poly(const vector<int> &v): a(v) {}
		poly(const initializer_list<int> &v): a(v) {}
		int size() const { return a.size(); }
		void resize(int n) { a.resize(n); }
		int& operator[](int i) { return a[i]; }
		const int& operator[](int i) const { return a[i]; }
		poly operator-() const {
			auto b = a;
			for (auto& x : b) x = (Mod - x) % Mod;
			return poly(b);
		}
		poly mul_xn(int n) const {
			auto b = a;
			b.insert(b.begin(), n, 0);
			return poly(b);
		}
		poly mod_xn(int n) const {
			if (size() <= n)
				return *this;
			return poly({ a.begin(), a.begin() + n });
		}
		poly operator+(const poly& rhs) const { return poly(*this) += rhs; }
		poly operator-(const poly& rhs) const { return poly(*this) -= rhs; }
		poly operator*(const poly& rhs) const { return poly(*this) *= rhs; }
		poly& operator+=(const poly& rhs) {
			if (size() < rhs.size())
				resize(rhs.size());
			for (int i = 0; i < rhs.size(); ++i) (a[i] += rhs[i]) %= Mod;
			return *this;
		}
		poly& operator-=(const poly& rhs) {
			if (size() < rhs.size())
				resize(rhs.size());
			for (int i = 0; i < rhs.size(); ++i) (a[i] -= rhs[i] - Mod) %= Mod;
			return *this;
		}
		poly& operator*=(poly rhs) {
			int sz = getsz(size() + rhs.size() - 1);
			resize(sz), rhs.resize(sz), ntt(a, 1), ntt(rhs.a, 1);
			for (int i = 0; i < sz; ++i) a[i] = 1LL * a[i] * rhs[i] % Mod;
			return ntt(a, -1), * this;
		}
		poly derivation() const {
			int n = size();
			if (!n)
				return poly();
			vector<int> ret(n - 1);
			for (int i = 1; i < n; ++i) ret[i - 1] = 1LL * a[i] * i % Mod;
			return poly(ret);
		}
		poly integral() const {
			int n = size();
			if (!n)
				return poly();
			vector<int> ret(n + 1), inv(n + 1, 1);
			for (int i = 2; i <= n; ++i) inv[i] = 1LL * inv[Mod % i] * (Mod - Mod / i) % Mod;
			for (int i = 1; i <= n; ++i) ret[i] = 1LL * a[i - 1] * inv[i] % Mod;
			return poly(ret);
		}
		poly inv(int n) const {
			assert(a[0] != 0), n = getsz(n);
			poly ret({(int)Pow(a[0], Mod - 2)});
			for (int k = 2; k <= n; k <<= 1) ret *= (poly({2}) - mod_xn(k) * ret).mod_xn(k);
			return ret.mod_xn(n);
		}
		poly log(int n) const {
			assert(a[0] == 1), n = getsz(n);
			return (derivation() * inv(n)).integral().mod_xn(n);
		}
		poly exp(int n) const {
			assert(a[0] == 0), n = getsz(n);
			poly ret({1});
			for (int k = 2; k <= n; k <<= 1) ret = (ret * (poly({1}) + mod_xn(k) - ret.log(k))).mod_xn(k);
			return ret.mod_xn(n);
		}
	};
}
using polynomial::poly;

计算几何

基本定义

const double pi=acos(-1),eps=1e-9;
int dcmp(double x,double y=0){
	return abs(x-y)<eps?0:(x<y?-1:1);
}
struct Point{
	double x,y;
	bool operator<(const Point &p){return dcmp(x,p.x)?x<p.x:y<p.y;}
	Point operator+(const Point &p){return {x+p.x,y+p.y};}
	Point operator-(const Point &p){return {x-p.x,y-p.y};}
	Point operator*(double _k){return {x*_k,y*_k};}
	Point operator/(double _k){return {x/_k,y/_k};}
	double operator*(const Point &p){return x*p.y-y*p.x;}
	double dot(const Point &p){return x*p.x+y*p.y;}
	double dist(){return hypot(x,y);}
};
struct Circle{
	Point p;
	double r;
	Point at(double theta){
		return {p.x+r*cos(theta),p.y+r*sin(theta)};
	}
};
struct Line{Point p,vec;};

其他

Point intersect(const Line &p1,const Line &p2){
	double _k=(p2.p-p1.p)*p2.vec/(p1.vec*p2.vec);
	return p1.p+p1.vec*_k;
}
Line mid_perp(const Point &p1,const Point &p2){
	auto _p=p1-p2;
	return {(p1+p2)/2,{_p.y,-_p.x}};
}
Circle circum(const Point &p1,const Point &p2,const Point &p3){
	auto _p=intersect(mid_perp(p1,p2),mid_perp(p2,p3));
	return {_p,Dist(_p,p1)};
}

图论

最大流

template<typename T>
struct MFGraph{
	static constexpr T Inf=numeric_limits<T>::max();
	const int n;
	struct Edge{
		int v;
		T w;
	};
	vector<Edge> e;
	vector<vector<int>> g;
	vector<int> cur,dis,q;
	MFGraph(int _n):n(_n),g(n+1){}
	bool bfs(int s,int t){
		dis.assign(n+1,0),q.assign(n+2,0);
		int head=1,tail=0;
		q[++tail]=s,dis[s]=1;
		while(head<=tail){
			int u=q[head++];
			for(int i:g[u]){
				int v=e[i].v;
				if(e[i].w&&!dis[v]){
					dis[v]=dis[u]+1,q[++tail]=v;
					if(v==t) return 1;
				}
			}
		}
		return 0;
	}
	T dinic(int u,int t,T flow){
		if(u==t) return flow;
		T rest=flow;
		for(int i=cur[u];i<int(g[u].size())&&rest;++i){
			cur[u]=i;
			int j=g[u][i],v=e[j].v;
			if(e[j].w&&dis[v]==dis[u]+1){
				T k=dinic(v,t,min(rest,e[j].w));
				if(!k) dis[v]=0;
				e[j].w-=k,e[j^1].w+=k,rest-=k;
			}
		}
		return flow-rest;
	}
	void add_edge(int u,int v,T w){
		g[u].push_back(e.size()),e.push_back({v,w});
		g[v].push_back(e.size()),e.push_back({u,0});
	}
	T flow(int s,int t){
		T res=0;
		while(bfs(s,t)){
			cur.assign(n+1,0);
			T flow;
			while((flow=dinic(s,t,Inf))) res+=flow;
		}
		return res;
	}
};

费用流

template<typename T>
struct MCFGraph{
	static constexpr T Inf=numeric_limits<T>::max();
	const int n;
	struct Edge{int v;T w,c;};
	vector<Edge> e;
	vector<vector<int>> g;
	vector<int> pre;
	vector<T> dis,aug;
	MCFGraph(int _n):n(_n),g(n+1),pre(n+1),aug(n+1){}
	bool spfa(int s,int t){
		dis.assign(n+1,Inf);
		vector<int> inq(n+1),q;
		q.push_back(s);
		dis[s]=0,inq[s]=1,aug[s]=Inf,aug[t]=0;
		For(j,0,int(q.size())-1){
			int u=q[j];inq[u]=0;
			for(int i:g[u]){
				int v=e[i].v;
				if(e[i].w&&dis[v]>dis[u]+e[i].c){
					dis[v]=dis[u]+e[i].c,pre[v]=i;
					aug[v]=min(e[i].w,aug[u]);
					if(!inq[v]) q.push_back(v),inq[v]=1;
				}
			}
		}
		return dis[t]<Inf;
	}
	void add_edge(int u,int v,T w,T c){
		g[u].push_back(e.size()),e.push_back({v,w,c});
		g[v].push_back(e.size()),e.push_back({u,0,-c});
	}
	pair<T,T> flow(int s,int t){
		T res=0,cost=0;
		while(spfa(s,t)){
			res+=aug[t];
			for(int u=t;u!=s;u=e[pre[u]^1].v){
				e[pre[u]].w-=aug[t],e[pre[u]^1].w+=aug[t];
				cost+=aug[t]*e[pre[u]].c;
			}
		}
		return {res,cost};
	}
};

数据结构

哈希表

template<typename Key,typename Val,typename Hash=hash<Key>>
struct HashTable{
	static constexpr int B=3141592,E=1e5;
	const Hash h;
	bool vis[B+E];
	Key key[B+E];
	Val val[B+E];
	HashTable():h(Hash()),vis(){}
	size_t locate(const Key &x){
		size_t i;
		for(i=h(x)%B;vis[i]&&key[i]!=x;++i);
		return i;
	}
	bool insert(const Key &x,const Val &y){
		size_t i=locate(x);
		if(vis[i]) return 0;
		vis[i]=1,key[i]=x,val[i]=y;
		return 1;
	}
	Val *find(const Key &x){
		size_t i=locate(x);
		return (vis[i]?val+i:nullptr);
	}
};
posted @ 2021-10-21 18:52  Alan_Zhao_2007  阅读(288)  评论(0编辑  收藏  举报