板子+公式(修补中)

图方便

没有写的我会在后面打\


图论
--树相关 \
--欧拉回路
void dfs(int x,int y){
	if(y!=0){
		vis[x][y]++;
		vis[y][x]++;
	}
	for(int i=1;i<=500;i++){
		if(ma[i][x]!=0&&vis[i][x]<mp[i][x]) dfs(i,x);
	}
	lu[++tot]=x;
}
int main(){
    dfs(start,0);
}
--最短路相关
----floyed最小环
int floyed(){
    int minn=INF;
     for(int k=1;k<=n;k++){
		for(int i=1;i<k;i++){
			for(int j=i+1;j<k;j++){
				minn=min(minn,dis[i][j]+g[i][k]+g[k][j]);
			}
		}
		for(int i=1;i<=n;i++){
			if(i==k) continue;
			for(int j=1;j<=n;j++){
				if(i==j||j==k) continue;
				if(dis[i][j]>dis[i][k]+dis[k][j]){
					dis[i][j]=dis[i][k]+dis[k][j];
				}
			}
		}	
	}
    return minn;
}
----floyed传递闭包(bitset优化)
bitset<N> dp[N];
void Floyd(){
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
            if(d[i][k]) d[i]|=d[k];
}
----dijkstra
priority_queue<node> q;
void dij(int s){
	memset(dis,0x3f,sizeof(dis));
	memset(vis,0,sizeof(vis));
	q.push({0,s});
	dis[s]=0;
	while(!q.empty()){
		node tmp=q.top();
		q.pop();
		int x=tmp.pos,y=tmp.dis;
		if(vis[x]) continue;
		vis[x]=1;
		for(int i=head[x];i;i=e[i].next){
			int y=e[i].to;
			if(dis[y]>dis[x]+e[i].w){
				dis[y]=dis[x]+e[i].w;
				if(!vis[y]) q.push((node){dis[y],y});
			}
		}
	}
----spfa判负环
int spfa(int s){
    memset(dis,0x3f,sizeof(dis));
	q.push(s);
	flag[s]=1;
	dis[s]=0;
	while(!q.empty()){
		int k=q.front();
		for(int i=head[k];i;i=e[i].next){
			int y=e[i].to;
			if(dis[y]<dis[k]+e[i].w){
				dis[y]=dis[k]+e[i].w;
                vis[i]=vis[k]+1;
				if(vis[i]>=n) return 1;
				if(!flag[y]){
					q.push(y);
					flag[y]=1;
				}
			}
		}
		flag[k]=0;
		q.pop();
	}
}
--最小生成树(kruskal)
struct edd{
	int x,y,z;
}tuu[M];
struct egde{
	int to,next,w;
}e[M];
int n,m,dad[N];
void add(int u,int v,int w){ }
int find(int x){ }
void kruskal(){
	for(int i=1;i<=n;i++) dad[i]=i;
	sort(tuu+1,tuu+m+1);
	for(int i=1;i<=m;i++){
		int fx=find(tuu[i].x),fy=find(tuu[i].y);
		if(fx!=fy){
			add(tuu[i].x,tuu[i].y,tuu[i].z);
			dad[fx]=fy;
		}
	}
}
--拓扑排序
priority<int,vector<int>,greater<int> > q;
void tuopu(){
	for(int i=1;i<=n;i++)	
		if(!ru[i]) q.push(i);
	int num=0,x;
	while(!q.empty()){
		x=q.top(),num++; 
		ans[++tot]=x;
		q.pop();
		for(int i=head[x];i;i=e[i].next){
			ru[e[i].to]--;
			if(!ru[e[i].to]) q.push(e[i].to);
		}
	}
	//ans数组即为拓扑序 
}
--tarjan
----缩点
void tarjan(int x){
	vis[x]=1,dfn[x]=low[x]=++cnt,t[++tot]=x;
	for(int i=head[x];i;i=e[i].next){
		if(!dfn[e[i].to]) tarjan(e[i].to);
		if(vis[e[i].to]) low[x]=min(low[e[i].to],low[x]);
	}
	if(dfn[x]==low[x]){
		sum1++;
		while(1){
			sum[sum1]++;
			vis[t[tot]]=0;
			col[t[tot--]]=sum1;
			if(x==t[tot+1]) break;
		}
	}
}
----割点
void tarjan(int x){
	//cut[i]表示点i是否为割点 
	dfn[x]=low[x]=++cnt;
	int son=0;
	for(int i=head[x];i;i=e[i].next){
		if(!dfn[e[i].to]){
			tarjan(e[i].to);
			low[x]=min(low[x],low[e[i].to]);
			if(low[e[i].to]>=dfn[x]){
				son++;
				if(x!=root||son>1) cut[x]=1;
			}
		}
		else low[x]=min(low[x],dfn[e[i].to]);
	}
}
int main(){
	//...
	for(int i=1;i<=n;i++){
		if(!dfn[i]){
			root=i;
			tarjan(i);
		}
	}
	return 0;
}
----割边
void tarjan(int x,int root){
	//cut[i]表示边i是否为割边 
    //注:使用链式前向星
	dfn[x]=low[x]=++cnt;
	for(int i=head[x];i;i=e[i].next){
		if(!dfn[e[i].to]){
			tarjan(e[i].to);
			low[x]=min(low[x],low[e[i].to]);
			if(low[e[i].to]>dfn[x]) cut[i]=1;
		}
		else if(e[i].to!=root) low[x]=min(low[x],dfn[e[i].to]);
	}
}
int main(){
	//...
	for(int i=1;i<=n;i++)
		if(!dfn[i]) tarjan(i,i);
	//...
	return 0;
}
----点双
#include<bits/stdc++.h>
#define N 500005
#define M 4000005
using namespace std;
struct egde{
	int to,next;
}e[N];
int cut[N];
int n,m,num,cnt,top,root,dfn[N],low[N],t[N];
int tot,head[N];
vector<int> dcc[N];
void add(int u,int v){
	if(u==v) return;
	e[++tot].to=v;
	e[tot].next=head[u];
	head[u]=tot;
}
void tarjan(int x){
	dfn[x]=low[x]=++cnt,t[++top]=x;
	if(!head[x]&&x==root){
		dcc[++num].push_back(x);
		return;
	}
	int son=0;
	for(int i=head[x];i;i=e[i].next){
		if(!dfn[e[i].to]){
			tarjan(e[i].to);
			low[x]=min(low[x],low[e[i].to]);
			if(low[e[i].to]>=dfn[x]){
				son++,num++;
				if(x!=root||son>1) cut[x]=1;
				int y;
				do{
					y=t[top--];
					dcc[num].push_back(y);
				}while(y!=e[i].to);
				dcc[num].push_back(x);
			}
		}
		else low[x]=min(low[x],dfn[e[i].to]);
	}
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int a,b;
		cin>>a>>b;
		add(a,b);
		add(b,a);
	}
	for(int i=1;i<=n;i++)
		if(!dfn[i]){
			root=i;
			tarjan(i);
		}
	cout<<num<<"\n";
	for(int i=1;i<=num;i++){
		cout<<dcc[i].size()<<" ";
		for(int j=0;j<dcc[i].size();j++)
			cout<<dcc[i][j]<<" ";
		cout<<"\n";
	}
	return 0;
}
----边双
#include<bits/stdc++.h>
#define N 500005
#define M 4000005
using namespace std;
struct egde{
	int to,next;
}e[M];
int n,m,cnt,num,top,dfn[N],low[N],t[N];
int tot=1,head[M];
vector<int> dcc[N];
void add(int u,int v){
	e[++tot].to=v;
	e[tot].next=head[u];
	head[u]=tot;
}
void tarjan(int x,int fa){
	dfn[x]=low[x]=++cnt,t[++top]=x;
	for(int i=head[x];i;i=e[i].next){
		int y=e[i].to;
		if(i==(fa^1)) continue;
		if(!dfn[y]) tarjan(y,i);
		low[x]=min(low[x],low[y]);
	}
	if(dfn[x]==low[x]){
		num++;
		int y;
		do{
			y=t[top--];
			dcc[num].push_back(y);
		}while(x!=y);
	}
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int a,b;
		cin>>a>>b;
		add(a,b);
		add(b,a);
	}
	for(int i=1;i<=n;i++)
		if(!dfn[i]) tarjan(i,0);
	cout<<num<<"\n";
	for(int i=1;i<=num;i++){
		cout<<dcc[i].size()<<" ";
		for(int j=0;j<dcc[i].size();j++){
			cout<<dcc[i][j]<<" ";
		}
		cout<<"\n";
	}
	return 0;
}
--lca
----dfs序求
#define lca_min(x,y) (dfn[x]<dfn[y])?x:y
void dfs(int x,int fa){
	dfn[x]=++cnt,st[cnt][0]=fa;
	for(int i=head[x];i;i=e[i].next){
		if(!dfn[e[i].to]) dfs(e[i].to,x);
	}
}
void init(){
    dfs(root,0);
	for(int j=1;(1<<j)<=n;j++){
		for(int i=1;i+(1<<j-1)<=n;i++){
			st[i][j]=lca_min(st[i][j-1],st[i+(1<<j-1)][j-1]);
		}
	}
}
int lca(int u,int v){
	if(u==v) return u;
	u=dfn[u],v=dfn[v];
	if(u>v) swap(u,v);
	lg=log2(v-u);
	u++;
	return lca_min(st[u][lg],st[v-(1<<lg)+1][lg]);
}
----树剖求
//树链剖分详见“图论--树链剖分”
int lca(int x,int y){
	if(x==y) return x;
	while(top[x]!=top[y]){
		if(dep[top[x]]>=dep[top[y]]) x=fa[top[x]];
		else y=fa[top[y]];
	}
	if(dep[x]<dep[y]) return x;
	return y;
}
--二分图判定
void dfs(int x,int now){
	if(cnt1==-1) return;
	if(col[x]!=-1){
		if(now!=col[x]) cnt1=-1;
		else return;
	}
	col[x]=now;
	if(now==0) cnt1++;
	else cnt2++;
	for(int i=head[x];i;i=e[i].next){
		dfs(e[i].to,now^1);
		if(cnt1==-1) return;
	}
}
void pan(){
	memset(col,-1,sizeof(col));
	for(int i=1;i<=n;i++){
		if(col[i]==-1){
			cnt=0,cnt2=0;
			dfs(i,1);
			if(cnt1==-1){
				cout<<"false";
				return;
			}
		}
	}
	cout<<"true";
}
--树链剖分 \

请在“数据结构-线段树”寻找线段树模板的区间修改,区间查询

----路径修改(极值) \
----路径修改(求和) \
----路径查询(极值) \
----路径查询(求和) \
数学相关 \
--高斯消元 \
--数论 \
----唯一分解定理 \
----线性筛素数(+欧拉函数) \
----gcd/lcm \
----试除法求欧拉函数 \
----欧拉定理 \
----扩展欧拉定理 \
----秦九昭算法(计算多项式) \
----裴蜀定理(贝祖定理) \
----扩展欧几里得 \
----乘法逆元 \
------费马小定理求解 \
------欧拉定理求解 \
------扩展欧几里得求解 \
------线性求解 \
--组合数学 \
----排列组合 \
----lusas定理 \
----扩展lucas定理 \
----二项式反演 \
----容斥原理 \
----中国剩余定理(crt) \
----扩展中国剩余定理 \
----bsgs \
----卡特兰数 \
----prufer序列 \
数据结构 \
--st表 \
--树状数组 \
--线段树 \
--单调队列/单调栈 \
--并查集 \
动态规划(DP)
--背包DP \
--线性DP \
--区间DP \
--坐标DP \
--树形DP ```cpp void dfs(int x,int fa){ for(int i=head[x];i;i=e[i].next){//遍历子节点 dfs(e[i].to,x)//递归处理子树 //由子节点转移到父节点 } } ```
--换根DP \
--高精度(重载运算符)
#include<bits/stdc++.h>
#define N 10005
#define base 100000
using namespace std;
struct llong{
	int len,s[N];
	//定义时初始化 
	llong(){
		len=1;
		memset(s,0,sizeof(s));
	}
	llong(int h){
		len=0;
		while(h) s[++len]=h%base,h/=base;
	}
	//字符串、整形转高精 
	void str(string kkk){
		len=1;
		memset(s,0,sizeof(s));
		int tl=kkk.size(),k=1;
		for(int i=0;i<tl;i++){
			s[len]+=(kkk[tl-i-1]-'0')*k,k*=10;
			if(k==base) ++len,k=1;
		}
	}
	void init(int h){
		len=0;
		while(h) s[++len]=h%base,h/=base;
	}
	//去前导零 
	void tui(){
		while(len>1&&!s[len]) len--;
	}
	//高精度输入输出 
	void read(){
		string tt;
		cin>>tt;
		str(tt);
	}
	void out(){
		tui();
		cout<<s[len];
		for(int i=len-1;i;i--) cout<<setw(4)<<setfill('0')<<s[i];
	}
	//高精和高精的比较 
	int operator>(llong x)const{
		if(x.len!=len) return len>x.len;
		for(int i=len;i;i--)
			if(x.s[i]!=s[i]) return s[i]>x.s[i];
		return 0;
	}
	int operator<(llong x)const{
		return x>*this;
	}
	int operator==(llong x)const{
		return !(x>*this||*this>x);
	}
	int operator>=(llong x)const{
		return !(x>*this);
	}
	int operator<=(llong x)const{
		return !(*this>x);
	}
	// +
	llong operator+(llong x)const{
		llong c;
		c.len=max(len,x.len)+1;
		for(int i=1;i<c.len;i++){
			c.s[i]+=s[i]+x.s[i];
			c.s[i+1]+=c.s[i]/base;
			c.s[i]%=base;
		}
		c.tui();
		return c;
	}
	// -
	llong operator-(llong x)const{
		llong c,kkk=*this;
		c.len=len;
		for(int i=1;i<=c.len;i++){
			c.s[i]=kkk.s[i]-x.s[i];
			if(c.s[i]<0) kkk.s[i+1]--,c.s[i]+=base;
		}
		c.tui();
		return c;
	}
	// *
	llong operator*(llong x)const{
		llong c;
		c.len=len+x.len+1;
		for(int i=1;i<=len;i++)
			for(int j=1;j<=x.len;j++){
				c.s[i+j-1]+=s[i]*x.s[j];
				c.s[i+j]+=c.s[i]/base;
				c.s[i+j-1]%=base;
			}
		c.tui();
		return c;
	}
	// /
	llong operator/(llong x)const{
		llong c,yu;
		c.len=len;
		for(int i=len;i>=1;i--){
			yu=yu*base+s[i];
			int l=0,r=base,mid;
			while(l<r){
				mid=(l+r+1)>>1;
				if(x*mid<=yu) l=mid;
				else r=mid-1;
			}
			yu=yu-x*l,c.s[i]=l;
		}
		c.tui();
		return c;
	}
	llong operator%(llong x)const{
		llong yu;
		for(int i=len;i>=1;i--){
			yu=yu*base+s[i];
			int l=0,r=base,mid;
			while(l<r){
				mid=(l+r+1)>>1;
				(x*mid<=yu)?(l=mid):(r=mid-1);
			}
			yu=yu-x*l;
		}
		return yu;
	}
	//重载各种高精与低精的运算
	llong operator+(int x)const{
		llong c(x);
		return *this+c;
	}
	llong operator-(int x)const{
		llong c(x);
		return *this-c;
	}
	llong operator*(int x)const{
		llong c(x);
		return *this*c;
	}
	llong operator/(int x)const{
		llong c(x);
		return *this/c;
	}
	llong operator%(int x)const{
		llong c(x);
		return *this%c;
	}
}a,b;
int main(){
    while(1){
        a.read();
	    b.read();
	    cout<<">  : "<<(a>b)<<"\n";
	    cout<<"<  : "<<(a<b)<<"\n";
	    cout<<">= : "<<(a>=b)<<"\n";
	    cout<<"<= : "<<(a<=b)<<"\n";
	    cout<<"=  : "<<(a==b)<<"\n";
	    llong t1=a+b,t2=a-b,t3=a*b,t4=a/b,t5=a%b;
	    cout<<"a+b : ";
	    t1.out();
	    cout<<"\n";
	    cout<<"a-b : ";
	    t2.out();
	    cout<<"\n";
	    cout<<"a*b : ";
	    t3.out();
	    cout<<"\n";
	    cout<<"a/b : ";
	    t4.out();
	    cout<<"\n";
	    cout<<"a%b : ";
	    t5.out();
	    cout<<"\n";
    }
}
--二分
----向左(最大值最小)
while(l<r){
	int mid=(l+r)>>1;
	if(check(mid)) r=mid;
	else l=mid+1;
}
----向右(最小值最大)
while(l<r){
	int mid=(l+r+1)>>1;
	if(check(mid)) l=mid;
	else r=mid-1;
}
--字符串输入
void read(string &t){
    char d;
	t="",d=getchar();
	while(d=='\r'||d=='\n') d=getchar();
	while(d!='\r'&&d!='\n') t+=d,d=getchar();
}
--随机数种子
struct _timeb T;
_ftime(&T);
mt19937 rand(T.millitm);
--快读快写

感谢 @
大佬提供的快读快写(本人修改了一些)

----快读
#define SIZE (1<<20)
#define gc() (p1==p2&&(p2=(p1=in)+fread(in,1,SIZE,stdin),p1==p2)?EOF:*p1++)
char in[SIZE],*p1=in,*p2=in;
template<typename type>
inline void read(type &x){
    x=0;bool flag(0);char ch=gc();
    while(!isdigit(ch))flag^=(ch=='-'),ch=gc();
    while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=gc();
    flag?x=-x:0;
}
#undef SIZE
#undef gc
----快写
#define SIZE (1<<20)
char out[SIZE],*p3=out;
#define fl() (fwrite(p3=out,1,SIZE,stdout))
#define pc(ch) (p3==out+SIZE&&fl(),*p3++=(ch))
template<typename type>
inline void write(type x,bool flag=1){
    x<0?x=-x,pc('-'):0;
    static short Stack[50],top(0);
    do Stack[++top]=x%10,x/=10;while(x);
    while(top)pc(Stack[top--]|48);
    flag?pc('\n'):pc(' ');
}
#undef SIZE
#undef pc
#undef fl
posted @ 2024-10-26 22:58  skx_515  阅读(15)  评论(0)    收藏  举报