0
点赞
收藏
分享

微信扫一扫

临时抱佛脚算法模板【后续更新】

往复随安_5bb5 2022-04-13 阅读 101

快速排序:

#include<iostream>
#include<algorithm>
using namespace std;

const int N=100010;

vector<int> ans;
int n;

void quick(int min,int max){
    
    if(min>=max)  return ;
    
    int x=ans[min+max>>1],l=min-1,r=max+1;
    
    while(l<r){
        
        do l++;
        while(ans[l]<x);
        
        do r--;
        while(ans[r]>x);
        
        if(l<r) swap(ans[l],ans[r]);
        
    }
    
    quick(min,r);
    quick(r+1,max);
}

int main(){
    
    cin>>n;
    
    for(int i=0;i<n;i++){
        int x; cin>>x;
        
        ans.push_back(x);
    }
    
    quick(0,n-1);
    
    for(auto t:ans)
        cout<<t<<' ';
}

归并排序:【归并排序可以求逆序对,也可以求出只能交换相邻两个数时,最少需要交换多少次】

#include<iostream>
#include<algorithm>
using namespace std;

const int N=100010;

vector<int> ans;
int n;
int tmp[N];

void meger(int min,int max){
    
    if(min>=max) return;
    
    int mid=min+max>>1;
    
    meger(min,mid); meger(mid+1,max);
    
    int l=min,r=mid+1,fur=min;
    
    while(l<=mid&&r<=max){
        
        if(ans[l]<ans[r]) tmp[fur++]=ans[l++];
        else tmp[fur++]=ans[r++];
        
    }
    
    while(l<=mid) tmp[fur++]=ans[l++];
    while(r<=max) tmp[fur++]=ans[r++];
    
    for(int i=min;i<=max;i++){
        ans[i]=tmp[i];
    }
    
}

int main(){
    
    cin>>n;
    
    for(int i=0;i<n;i++){
        int x; cin>>x;
        
        ans.push_back(x);
    }
    
    meger(0,n-1);
    
    for(auto t:ans) cout<<t<<' ';
    
}

二维前缀和:

#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

const int N=1010;

ll st[N][N];
int n,m,k;

void init(){
    
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            
            st[i][j]=st[i-1][j]+st[i][j-1]-st[i-1][j-1]+st[i][j];
            
        }
    }
    
}

ll query(int x1,int y1,int x2,int y2){
    
    return st[x2][y2]-st[x1-1][y2]-st[x2][y1-1]+st[x1-1][y1-1];
    
}

int main(){
    
    cin>>n>>m>>k;
    
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
            cin>>st[i][j];
    }
    
    init();
    
    while(k--){
        
        int x1,y1,x2,y2; cin>>x1>>y1>>x2>>y2;
        
        cout<<query(x1,y1,x2,y2)<<endl;
        
    }
    
}

二维差分:

#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

const int N=1010;

ll st[N][N];
int n,m,k;

void insert(int x1,int y1,int x2,int y2,int c){
    
    st[x1][y1]+=c;
    st[x1][y2+1]-=c; st[x2+1][y1]-=c;
    st[x2+1][y2+1]+=c;
}

void init(){
    
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            
            st[i][j]=st[i-1][j]+st[i][j-1]-st[i-1][j-1]+st[i][j];
        }
    }
    
}

int main(){
    
    cin>>n>>m>>k;
    
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            int x; cin>>x;
            insert(i,j,i,j,x);
        }
    }
    
    while(k--){
        
        int x1,y1,x2,y2,w; cin>>x1>>y1>>x2>>y2>>w;
        
        insert(x1,y1,x2,y2,w);
    }
    
    init();
    
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
            cout<<st[i][j]<<' ';
        cout<<endl;
    }
    
}

高精度除法:

#include<vector>
#include<algorithm>
#include<iostream>
#include<string>
#define ll long long
using namespace std;

string a;
vector<ll> ans;
ll b,r;

void div(vector<ll> &ans,ll b){
    
    int t=0;
    vector<ll> mid;
    
    for(int i=0;i<ans.size();i++){
        
        t=t*10+ans[i];
        mid.push_back(t/b);
        t%=b;
    }
    
    r=t;
    
    reverse(mid.begin(),mid.end());
    
    while(!mid.back()&&mid.size()>1) mid.pop_back();
    
    reverse(mid.begin(),mid.end());
    
    ans=mid;
}

int main(){
    
    cin>>a>>b;
    
    for(int i=0;i<a.size();i++) ans.push_back(a[i]-'0');
    
    div(ans,b);
    
    for(auto t:ans) cout<<t;
    cout<<endl<<r;
    
}

高精度乘法:

#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#define ll long long
using namespace std;

vector<ll> ans;
ll b;
string a;

void mul(vector<ll> &ans,ll b){
    
    vector<ll> mid; ll t=0;
    
    for(int i=0;i<ans.size()||t;i++){
        
        if(i<ans.size()) t+=b*ans[i];
        
        mid.push_back(t%10);
        t/=10;
    }
    
    while(!mid.back()&&mid.size()>1) mid.pop_back();
    
    ans=mid;
}

int main(){
    
    cin>>a>>b;
    
    for(int i=0;i<a.size();i++){
        ans.push_back(a[i]-'0');
    }
    
    reverse(ans.begin(),ans.end());
    
    mul(ans,b);
    
    for(int i=ans.size()-1;i>=0;i--) cout<<ans[i];
    
}

辗转相除法【欧几里得法】:

#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

ll a,b;

ll gcd(ll a,ll b){
    return !(a%b)?b:gcd(b,a%b);
}

int main(){
    
    cin>>a>>b;
    
    cout<<gcd(a,b);
    
}

拓展欧几里得算法:

#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

ll a,b;

ll exgcd(ll a,ll b,ll &x,ll &y){
    
    ll d=a;
    
    if(b){
        
        d=exgcd(b,a%b,y,x);
        y-=(a/b)*x;
    }else{
        x=1,y=0;
    }
    return d;
    
}

int main(){
    
    cin>>a>>b;
    
    ll x,y,m=exgcd(a,b,x,y);
    
    printf("%lld*%lld+%lld*%lld=%lld",a,x,b,y,m);
    
}

快速幂:

#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

ll a,b,mod;//a^b%mod
ll ans=1;

int main(){
    
    cin>>a>>b>>mod;
    
    for(int i=b;i;i>>=1){
        if(i&1) ans*=a,ans%=mod;
        a*=a; a%=mod;
    }
    
    cout<<ans;
    
}

素数筛【获得最小质因数】

#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

const int N=100010;

ll mi[N];
bool st[N];
ll n;

void get_prime(){
    
    mi[1]=1;
    
    for(int i=2;i<=n;i++){
        
        if(!st[i]){
            for(int j=i*2;j<=n;j+=i){
                st[j]=1; mi[j]=i;
            }
            mi[i]=i;
        }
    }
    
}

int main(){
    
    cin>>n;
    
    get_prime();
    
    for(int i=2;i<=n;i++)
        if(!st[i]) cout<<i<<' ';
    cout<<endl;
    
    for(int i=2;i<=n;i++)
        cout<<mi[i]<<' ';
    
}

获取因数:

#include<iostream>
#include<algorithm>
#include<vector>
#include<math.h>
#define ll long long
using namespace std;

ll a;
vector<ll> ans;

void get_num(int x){
    
    for(int i=1;i<=sqrt(x);i++){
        
        if(x%i==0){
            ans.push_back(i);
            ans.push_back(x/i);
        }
        
    }
    
}

int main(){
    
    cin>>a;
    
    get_num(a);
    
    sort(ans.begin(),ans.end());
    
    for(ll t:ans) cout<<t<<' ';
     
}

质因数分解【如果是对多个数分解,则要配合上面的素数筛】

#include<iostream>
#include<algorithm>
#include<vector>
#define ll long long
using namespace std;

ll a;
vector<ll> ans;

int main(){
    
    cin>>a;
    
    for(int i=2;i<=a/i;i++){
        
        while(!(a%i)){
            ans.push_back(i);
            a/=i;
        }
    }
    
    if(a!=1) ans.push_back(a);
    
    for(auto t:ans) cout<<t<<' ';
    
}

迪杰斯特拉【堆优化】:

#include<iostream>
#include <vector>
#include<algorithm>
#include<cstring>
#include<queue>
#define x first
#define y second
#define ll long long
using namespace std;

const int N=150010;

struct p{
    ll ne,w;
};
typedef pair<ll,ll> two;

vector<vector<p>> g(N);
int n,m;
ll dist[N];
bool st[N];

ll dj(){
    
    priority_queue<two,vector<two>,greater<two>> que;
    memset(dist,0x3f,sizeof dist);
    que.push({0,1});
    dist[1]=0;
    
    while(que.size()){
        
        two t=que.top();
        que.pop();
        if(st[t.y]) continue;
        
        st[t.y]=1;
        
        for(int i=0;i<g[t.y].size();i++){
            
            int id=g[t.y][i].ne,w=g[t.y][i].w;
            
            if(dist[id]>dist[t.y]+w){
                
                dist[id]=dist[t.y]+w;
                que.push({dist[id],id});
                
            }
            
        }
    }
    
    return dist[n]>1e9?-1:dist[n];
    
}

int main(){
    cin>>n>>m;
    
    for(int i=0;i<m;i++){
        
        ll a,b,w; cin>>a>>b>>w;
        
        g[a].push_back({b,w});
    }
    
    cout<<dj();
    
    
}

弗洛伊德算法:

#include<iostream>
#include <vector>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;

const int N=210;

ll w[N][N];
int n,m,k;

int main(){
    
    memset(w,0x3f,sizeof w);
    
    cin>>n>>m>>k;
    
    for(int i=0;i<m;i++){
        ll x,y,z; cin>>x>>y>>z;
        w[x][y]=min(w[x][y],z);
    }
    
    for(int i=1;i<=n;i++) w[i][i]=0;
    
    for(int k=1;k<=n;k++){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                w[i][j]=min(w[i][j],w[i][k]+w[k][j]);
            }
        }
    }
    
    while(k--){
        
        int a,b; cin>>a>>b;
        
        if(w[a][b]>1e9) cout<<"impossible"<<endl;
        else cout<<w[a][b]<<endl;
        
    }
    
}

模拟堆:

#include<iostream>
#include<algorithm>
using namespace std;

const int N=100010;

int n,m,cnt;
int st[N];

void down(int x){
    
    int t=x;
    
    if(t*2<=cnt&&st[t*2]<st[x]) x=t*2;
    
    if(t*2+1<=cnt&&st[t*2+1]<st[x]) x=t*2+1;
    
    if(t!=x){
        
        swap(st[x],st[t]);
        down(x);
    }
}

void up(int x){
    
    for(int i=x;i>=1;i/2){
        
        int fa=i/2;
        if(st[fa]>st[i]) swap(st[fa],st[i]);
        else break;
    }
    
}

int main(){
    
    cin>>n>>m; cnt=n;
    
    for(int i=1;i<=n;i++) cin>>st[i];
    
    for(int i=n/2;i>=1;i--) down(i);
    
    for(int i=0;i<m;i++){
        
        cout<<st[1]<<' ';
        st[1]=st[cnt--];
        down(1);
    }
    
}

举报

相关推荐

0 条评论