快速幂
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);//求下降的
}