进制转换
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1000;
int a[N];
char ch[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
void solve(){
int n,m;
cin>>n>>m; //n进制转m进制
string s;cin>>s;
for(int i =0;i<s.size();++i){
if(s[i] >= '0' && s[i] <='9')a[i] = s[i] - '0';
else a[i] = s[i] - 'A' + 10;
}
ll x = 0;
for(int i =0;i<s.size();++i)x = x*n + a[i];
//此时得到的数字x为n进制转成十进制后的数字
//接下来考虑转换成m进制
string ans;
while(x){
ans +=ch[x%m];
x /=m;
}
reverse(ans.begin() , ans.end());//别忘记反转
cout<<ans<<endl;
//ans即为转换后的数
}
int main(){
ios::sync_with_stdio(false);
cout.tie(0);
cin.tie(0);
solve();
return 0;
}
差分与前缀和(二维)
一维的比较简单,没什么好说的,这里主要实现一下二维
下面是二维前缀和的模板
for(int i =1;i<=;++i){
for(int j =1;j<=m;++j){
pre[i][j] = pre[i-1][j] + pre[i][j-1] - pre[i-1][j-1] + a[i][j];
}
}
while(q--){
int x1 , x2 , y1 , y2;
cin>>x1>>y1>>x2>>y2;
int ans = pre[x2][y2] - pre[x1-1][y2] - pre[x2][y1-1] + pre[x1-1][y1-1];
}
下面是二维差分的模板
void insert(int x1 , int x2 , int y1 , int y2 , int c){
dif[x1][y1] +=c;
dif[x1][y2+1] -=c;
dif[x2+1][y1] -=c;
dif[x2+1][y2+1] +=c;
}
for(int i =1;i<=n;++i){
for(int j =1;j<=m;++j){
insert(i , j , i , j , a[i][j]);
}
}
while(q--){
int x1 , x2 , y1 , y2,c;
cin>>x1>y1>>x2>>y2>>c;
intsert(x1 , y1 , x2 , y2 , c);
}
for(int i =1;i<=n;++i){
for(int j =1;j<=m;++j){
dif[i][j] += dif[i-1][j] + dif[i][j-1] - dif[i-1][j-1]
}
}
快速幂
int ksm(int a , int b){ //a的b次方
ll ans = 1;
while(b){
if(b&1)ans = ans * a %mod;
a = a*a%mod;
b >>=1;
}
return ans;
}
gcd和lcm
int gcd(int x , int y){
return y == 0 ?x : gcd(y , x%y);
}
int lcm(int x , int y){
return x*y/gcd(x,y);
}
背包问题
01背包
for(int i =1;i<=n;++i){
for(int j =v;j>=v[i];--j){ //倒着遍历背包
dp[j] = max(dp[j] , dp[j - v[i]]+w[i]);
}
}
完全背包
for(int i =1;i<=n;++i)
for(int j =v[i];j<=v;++j)
dp[j] = max(dp[j] , dp[j - v[i]]+w[i]);
多重背包
for(int i =1;i<=n;++i){
int v,w,s; //表示每个物品只能选s次
cin>>v>>w>>s;
for(int k =1;k<=s;s -=k , k += k){
for(int j =m;j>=k*v;--j)dp[j] = max(dp[j] ,dp[j -v*k]+w*k);
}
for(int j =m;j>=s*v;--j)dp[j] = max(dp[j] ,dp[j -v*s]+w*s);
}
二维费用背包
for(int i =1;i<=n;++i){
int v, m , w;
cin>>v>>m>>w;
for(int j =M;j>=m;--j){
for(int k = V;k>=v;--k){
dp[j][k] = max(dp[j][k] , dp[j-m][k-v]+w);
}
}
}
分组背包
for(int i =1;i<=n;++i){
for(int j =1;j<=V;++j)dp[i][j] = dp[i-1][j];
int s;cin>>s;
while(s--){
int v,w;
cin>>v>>w;
for(int k =V;k>=v;--k)dp[i][k] = max(dp[i][k] , dp[i-1][k-v]+w);
}
}
拓扑排序
void topsort()
{
while(!q.empty()){
auto now = q.front();
q.pop();
for(auto to : g[now]){
inedge[to]--;
if(inedge[to] == 0){
cout<<to<<endl;
q.push(to);
}
}
}
}
cin>>n>>m;
for(int i =1;i<=m;++i){
int a,b;
cin>>a>>b;
g[a].push_back(b);
inedge[b]++;
}
for(int i =1;i<=n;++i){
if(inedge[i] == 0){
cout<<i<<endl;
q.push(i);
}
}
toposort();
最短路
迪杰斯特拉(堆优化)
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define INF 0x3f3f3f3f
// #define x first
// #define y second
// #define int long long
// #define ll long long
typedef pair<int,int> pii;
const int mod = 998244353;
// const int mod = 80112002;
const int N = 2e5+9;
int n ,m;
int inedge[N];
vector<pii>g[N];
queue<pii>q;
void dijkstra()
{
q.push({0,s});//s是根
dis[s] = 0;
while(!q.empty()){
auto t = q.top();
q.pop();
int now = t.second;
if(vis[now])continue; //判断是否出列过
vis[now] = 1;
for(auto to : g[now]){
int v = to.second , w = to.first;
if(dis[now] + w < dis[v]){
dis[v] = dis[now] + w;
q.push({dis[v] , v});
}
}
}
}
void solve(){
memset(vis , false , sizeof(vis));
memset(dis , 0x3f , sizeof(dis));
cin>>n>>m;
for(int i =1;i<=m;++i){
int u,v,w;
cin>>u>>v>>w;
g[u].push_back({w,v});
}
dijk();
}
signed main(){
ios::sync_with_stdio(false);
cout.tie(0);
cin.tie(0);
int _ = 1;
// cin>>_;
while(_--){
solve();
}
return 0;
}
Floyd
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define INF 0x3f3f3f3f
// #define x first
// #define y second
// #define int long long
// #define ll long long
typedef pair<int,int> pii;
const int mod = 998244353;
// const int mod = 80112002;
const int N = 1001;
int g[N][N][N];
void solve(){
cin>>n>>m;
for(int i =1;i<=m;++i){
int u , v , w;
cin>>u>>v>>w;
g[u][v] = g[v][u] = min(g[u][v] , w);
}
for(int i =1;i<=n;++i)g[i][i] =0;
for(int k = 1;k<=n;++k){
for(int i =1;i<=n;++i){
for(int j =1;j<=n;++j){
g[i][j] = min(g[i][j] , g[i][k] + g[k][j]);
}
}
}
for(int i =1;i<=n;++i){
for(int j = 1;j<=n;++j){
cout<<g[i][j]<<endl;
}
}
}
signed main(){
ios::sync_with_stdio(false);
cout.tie(0);
cin.tie(0);
int _ = 1;
// cin>>_;
while(_--){
solve();
}
return 0;
}
最小生成树 kruskal
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
const int N = 2e5+9;
struct edge{
int x,y,w;
}e[N];
int fa[100000];
int ans ,cnt;
int find(int x){
return fa[x] = fa[x] ==x ? x : find(fa[x]);
}
bool cmp(edge a , edge b){
return a.w < b.w;
}
bool f =false;
void kruscal(){
for(int i =1;i<=m;++i){
int fx = find(e[i].x) , fy = find(e[i].y);
if(fx == fy)continue;
ans +=e[i].w;
fa[fx] = fy;
cnt++;
if(cnt == n-1){
f = true;
break;
}
}
}
signed main(){
ios::sync_with_stdio(false);
cout.tie(0);
cin.tie(0);
cin>>n>>m;
for(int i =1;i<=m;++i)cin>>e[i].x>>e[i].y>>e[i].w;
for(int i=1;i<=n;++i)fa[i] = i;
sort(e+1 ,e+1+m,cmp);
kruscal();
if(!f)cout<<"orz";
else cout<<ans;
return 0;
}
克鲁斯卡尔重构树
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define INF 0x3f3f3f3f
// #define x first
// #define y second
// #define int long long
// #define ll long long
const int mod = 998244353;
// const int mod = 80112002;
const int N = 2e5+9;
const int M = 3e5+9;
int n,m,q , id;
int val[N];
int pre[N];
struct edge{
int x , y , w;
}e[M];
vector<int>g[N];
bool cmp(edge a , edge b){
return a.w > b.w;
}
int find(int x){
return pre[x] = pre[x] ==x ? x : find(pre[x]);
}
void kruskal(){
id = n;
for(int i =1;i<=m;++i){
int x = e[i].x , y = e[i].y , w = e[i].w;
int fx = find(x) ,fy = find(y);
if(fx == fy)continue;
id++;
pre[fx] = id;
pre[fy] = id;
g[id].push_back(fx);
g[id].push_back(fy);
val[id] = w;
}
}
void solve(){
cin>>n>>m>>q;
for(int i =1;i<=m;++i){
cin>>e[i].x>>e[i].y>>e[i].w;
}
for(int i =1;i<=n*2;++i)pre[i] = i;
sort(e+1 , e+1+m ,cmp);
kruskal();//克鲁斯卡尔重构树
//树链剖分求lca
for(int i =1;i<=id;++i){
if(pre[i] == i){
dfs1(i , 0);
dfs2(i , i);
}
}
while(q--){
int a , b;
cin>>a>>b;
if(find(a) != find(b))cout<<-1<<endl;
else cout<<val[lca(a,b)]<<endl;
}
}
signed main(){
ios::sync_with_stdio(false);
cout.tie(0);
cin.tie(0);
int _ = 1;
while(_--){
solve();
}
return 0;
}
lca(树链剖分)
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define INF 0x3f3f3f3f
// #define x first
// #define y second
// #define int long long
// #define ll long long
typedef pair<int,int> pii;
const int mod = 998244353;
// const int mod = 80112002;
int fa[N] , son[N] , dep[N] , sz[N] , top[N];
void dfs1(int u , int father){
dep[u] = dep[father]+1;
fa[u] = father;
sz[u] = 1;
for(auto v : g[u]){
if(v == father)continue;
dfs1(v,u);
sz[u] +=sz[v];
if(sz[son[u]] < sz[v])son[u] = v;
}
}
void dfs2(int u , int t){
top[u] = t;
if(!son[u])return;
dfs2(son[u] , t);
for(auto v : g[u]){
if(v == fa[u] || v == son[u])continue;
dfs2(v , v);
}
}
int lca(int u , int v){
while(top[u] != top[v]){
if(dep[top[u]] < dep[top[v]])swap(u , v);
u = fa[top[u]];
}
return dep[u] < dep[v] ? u : v;
}
void solve(){
cin>>n>>m>>s;
int a , b;
for(int i =1;i<n;++i){
cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
dfs1(s , 0);
dfs2(s , s);
while(m--){
cin>>a>>b;
cout<<lca(a,b)<<endl;
}
}
signed main(){
ios::sync_with_stdio(false);
cout.tie(0);
cin.tie(0);
int _ = 1;
// cin>>_;
while(_--){
solve();
}
return 0;
}
二分
while(l < r){
int mid = (l+r+1)>>1;
if(check(mid))l = mid;
else r = mid - 1;
}
while(l < r){
int mid = (l+r)>>1;
if(check(mid))r = mid;
else l = mid +1;
}
浮点二分
double bsearch(double l , double r){
double eps = 1e-6;
while(r - l > eps){
double mid = (l+r)/2;
if(check(mid))r = mid;
else l = mid;
}
return l;
}