整理一下模板

快速幂

LL fast_pow(LL x,LL y){
	LL res = 1LL;
	x = x % mod;
	while(y){
		if(y & 1) res = res * x % mod;
		y >>= 1;// /2
		x = x * x % mod;
	}
	return res;
}

gcd + lcm

int gcd(int a,int b){
	if(b == 0) return a;
	return gcd(b,a % b);
}
int lcm(int a,int b){
	return a / gcd(a,b) * b;
}

二分内置

binary_search(first,last,value) //[first,last)中是否存在value(bool)
lower_search(first,last,value)	//............中>=value的第一个地址
upper_search(first,last,value)	//..............>..................

cout控制输出位数

#include<iomanip>
cout << setprecision(n) << fixed << ans;
setw(5)//预留五位不足右对齐

 

背包

int dp[1005],w[1005],v[1005],n,V;
cin >> n >> V;
for(int i = 1;i <= n; i++) scanf("%d",&v[i]);//value
for(int i = 1;i <= n; i++) scanf("%d",&w[i]);//weight
memset(dp,0,sizeof(dp));
//01
for(int i = 1;i <= n; i++){
	for(int j = V;j >= w[i]; j--){
		dp[j] = max(dp[j],dp[j - w[i]] + v[i]);
	}
}
cout << dp[V] << endl;

//完全
for(int i = 1;i <= V; i++) ans[i] = 1 << 30;//初始化极大
for(int i = 1;i <= n; i++){
	for(int j = w[i];j <= V;j++){
		ans[j] = min(ans[j],abs[j - w[i]] + p[i]);//价值最小     p 价值
	}
}

floyd

for(int k = 1;k <= n; k++){
	for(int i = 1;i <= n; i++){
		for(int j = 1;j <= n; j++){
			dis[i][j] = min(dis[i][j],dis[i][k] + dis[k][j]);
		}
	}
}

dijkstra

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>

using namespace std;
const int maxn = 1e5 + 4;
const int inf = 0x3f3f3f3f;
#define mp make_pair
#define PII pair<int,int>

int n,m,u,v,cost,s,t;
int d[maxn];
bool vis[maxn];
vector<PII> G[maxn];

void dij(int s){
	memset(d,inf,sizeof(d));
	memset(vis,0,sizeof(vis));
	d[s] = 0;
	while(1){
		int v = -1;
		for(int i = 1;i <= n; i++){
			if(!vis[i] && (v == -1 || d[v] > d[i])) v = i;
		}
		if(v == -1) break;//没得更
		vis[v] = 1;
		int len = G[v].size();
		for(int i = 0;i <= len - 1; i++){
			int u = G[v][i].first;
			if(vis[u]) continue;
			d[u] = min(d[u],d[v] + G[v][i].second);
		}
	}
}

int main()
{
	while(~scanf("%d %d",&n,&m)){//n个点 m条路
		for(int i = 1;i <= n; i++) G[i].clear();
		for(int i = 1;i <= m; i++){
			scanf("%d %d %d",&u,&v,&cost);
			G[u].push_back(mp(v,cost));
			G[v].push_back(mp(u,cost));
		}
		cin >> s >> t;//起点终点
		dij(s);
		cout << d[t] << endl;
	}
}

LCA

int LCA(int u,int v)
{
	if(deep[u] < deep[v])///默认u的深度大一点简化后面的问题
		swap(u,v);
	int h = deep[u] -  deep[v];///求出高度差

	for(int i = 0;i < 20; i++){///这个操作可以将u节点向上提升任意高度,觉得难懂就需要自己模拟一下过程
		if(h & (1 << i)){///二级制位上存在1就提升 1 << i步
			u = f[u][i];///u不断相上找its父节点
		}
	}
	if(u == v) return u; ///如果u == v表示 u就是v下面的分支节点
	//此时在同一dep
	for(int i = 19;i >= 0; i--){ ///找到第一个不相同的节点
		if(f[u][i] != f[v][i]){  ///还是利用了 1 2 4 可以任意组合出1-7所有的步数
			u = f[u][i];
			v = f[v][i];
		}
	}
	return f[u][0];  ///第一个不相同的节点的上一个就是最近公共祖先
}

LIS

int calc(int sign){
	fill(dp,dp + maxn,inf);
	int ans = 0;
	for(int i = 0;i < n; i++){
		int index = upper_bound(dp,dp + ans,a[i] * sign) - dp;
		//这个是求不严格的序列,如果要求严格的就用lower_bound
		dp[index] = a[i] * sign;
		ans = max(ans,index + 1);
	}
	return ans;
}
int lins(){
	return calc(1);//求上升的
}
int lnds(){
	return calc(-1);//求下降的
}

 

发布了31 篇原创文章 · 获赞 5 · 访问量 1383

猜你喜欢

转载自blog.csdn.net/qq_43685900/article/details/89787590