【模板】OI常用模板(待补充)

//PS:最近修改日期:2017-11-07  20:41:44

首先感觉这种模板类的东西写了还是很有意义的,毕竟时不时的可以拿出来借鉴一下。

现在因为刚开始写这一类的东西,所以说还不是很详细,若有读者感觉可以补充,欢迎反馈!!感激不尽!!

注意!在本篇文章中,有:

#include<bits/stdc++.h>

#define LL long long

typedef pair <int,int> pill;

using namespace std;

所以以下的LL指的就是long long 的数据类型。

并且pill 指的是2元整形容器pair<int,int>

 

目录:

一、读入优化

二、快速幂

三、Floyd算法

四、Dijkstra算法

五、Dijkstra算法的堆优化

六、欧几里得算法

七、扩展欧几里得

八、矩阵快速幂

九、ST表

一、读入优化    //读入数据的大小以MB作为单位的。

inline LL read(){
    LL base=0,flag=1;
    char ch='.';
    while(ch>'9'||ch<'0'){
        ch=getchar();
        if(ch=='-')    flag=-1;
    }
    while(ch>='0'&&ch<='9'){
        base=base*10+ch-'0';
        ch=getchar();
    };
    return flag*base;
}

二、快速幂    //输出(x^k)%p的值,满足k非常大,n也非常大

inline LL quick_pow(LL x,LL k){    
  LL base=1;
  while(k){     if(k&1)  base=(base*x)%p;     k>>=1;     x=(x*x)%p;   }   return base; }

三、Floyd算法    //求所有的节点到每个节点的最短路的距离

inline void Floyd (){
    memset(dis,0x3f,sizeof(dis));
    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];
            }
        }
    }
    return;
}

四、Dijkstra算法    //求n点到其他点的单源最短路径长度

inline void Dijkstra (int x){
    int min=1e9+1,place=0; 
    dis[x]=0;
    memset(dis,0x3f,sizeof(dis));
    memset(vis,false,sizeof(vis));
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(!vis[j]&&dis[j]<min){
                min=dis[j];
                place=j;
            }
        }
        if(place==0)break;
            vis[place]=true;
        for(int j=head[place];j!=-1;j=edge[j].next){
            if(!vis[edge[j].to]&&dis[edge[j].to]>(edge[j].dis+dis[place])){
                dis[edge[j].to]=edge[j].dis+dis[place];
            }
        }
    }
    return;
}

五、Dijkstra的堆优化    //求n点到其他点的单源最短路径长度

inline void Dijkstra (int x){
    priority_queue<pill,vector<pill>,greater<pill> >q;
    dis[s]=0;
    q.push(make_pair(dis[s],s));
    while(!q.empty()){
        pill temp=q.top();
        q.pop();
        numb=temp.second;
        if(vis[numb])continue;
        vis[numb]=1;
        for(int i=head[numb];i!=-1;i=edge[i].next){
            if(dis[edge[i].to]>dis[numb]+edge[i].dis){
                dis[edge[i].to]=dis[numb]+edge[i].dis;
                q.push(make_pair(dis[edge[i].to],edge[i].to));
            }
        }
    }
    return;
}

六、欧几里得算法    //求最大公约数  

inline LL gcd(LL a,LL b){
    if(a%b==0)return b;
        else return gcd(b,a%b);
}

 七、扩展欧几里得    //在求最大公约数的同时求ax+by=gcd(a,b)的整数解

inline LL exgcd(LL a,LL b,LL &x,LL &y){
    if(b==0){
        x=1;
        y=0;
        return a;
    }
    else{
        ans=exgcd(b,a%b,x,y);
        LL temp=x;
        x=y;
        y=temp-(a/b)*y;
        return ans;
    }
}

八、矩阵快速幂    //线性代数中比较重要的一课

struct Mat{
    LL mat[105][105];
}
Mat operator *(Mat a,Mat b){
    Mat c;
    memset(c.mat,0,sizeof(c.mat));
    for(int k=0;k<n;k++)
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                c.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
    return c;
}
void work(){
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++)
            scanf("%lld",&x.mat[i][j]);
            res.mat[i][i]=1;
        }
    }
    while(k){
            if(k&1)    res=res*x;
            k>>=1;
            x=x*x;
        }
}

 

九、ST表    //灵活运用二进制进行加速的访问操作 

inline void ST(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)    scanf("%d",&f[i][0]);
        LOG[0]=-1;    for(int i=1;i<=n;i++)        LOG[i]=LOG[i/2]+1;
        power[0]=1;    for(int i=1;i<=LOG[n];i++)   power[i]=power[i-1]*2;
        for(int j=1;j<=LOG[n];j++)
            for(int i=1;i<=n;i++)
                if(i+power[j-1]-1<=n)
                    f[i][j]=max(f[i][j-1],f[i+power[j-1]][j-1]);    
        return;
}

 

等待补充。。。。。。

 
 

 

原文地址:https://www.cnblogs.com/ACworker/p/7725467.html