蓝桥杯复习(自用)

进制转换

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值