各类算法模板

quick_sort(q, 0, n - 1);

 

快排

void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;

    int i = l - 1, j = r + 1, x = q[l + r >> 1];
    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j) swap(q[i], q[j]);
    }

    quick_sort(q, l, j);
    quick_sort(q, j + 1, r);
}

 归并排序

int a[N], tmp[N];

void merge_sort(int q[], int l, int r)
{
    if (l >= r) return;

    int mid = l + r >> 1;

    merge_sort(q, l, mid), merge_sort(q, mid + 1, r);

    int k = 0, i = l, j = mid + 1;
    while (i <= mid && j <= r)
        if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];
        else tmp[k ++ ] = q[j ++ ];
    while (i <= mid) tmp[k ++ ] = q[i ++ ];
    while (j <= r) tmp[k ++ ] = q[j ++ ];

    for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
}

 

堆排序

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

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

二分

        int l = 0, r = n - 1;             
        while (l < r)
        {
            int mid = l + r >> 1;
            if (q[mid] >= x) r = mid;
            else l = mid + 1;
        }
          
         int l = 0, r = n - 1;
         while (l < r)
         {
             int mid = l + r + 1 >> 1;
             if (q[mid] <= x) l = mid;
             else r = mid - 1;
         }

单链表

int head,e[N],ne[N],idx;
void init()//初始化
{
    head = -1;
    idx=0;
}
void add_to_head(int x)//建表
{
    e[idx] = x,ne[idx]=head,head=idx++;
}
void add(int k,int x)//插入链表
{
    e[idx]=x,ne[idx]=ne[k],ne[k]=idx++;
}
void remove(int k)//删除链表
{
    ne[k]=ne[ne[k]];
}

双链表

    // 0是左端点,1是右端点
    r[0] = 1, l[1] = 0;
    idx = 2;

 

int e[N], l[N], r[N], idx;

// 在节点a的右边插入一个数x
void insert(int a, int x)
{
    e[idx] = x;
    l[idx] = a, r[idx] = r[a];
    l[r[a]] = idx, r[a] = idx ++ ;
}

// 删除节点a
void remove(int a)
{
    l[r[a]] = l[a];
    r[l[a]] = r[a];
}

KMP

    int n,m;
    string s,p;
    cin >> n >> p + 1 >> m >> s + 1;//下标从1开始

    for (int i = 2, j = 0; i <= n; i ++ )
    {
        while (j && p[i] != p[j + 1]) j = ne[j];
        if (p[i] == p[j + 1]) j ++ ;
        ne[i] = j;
    }

    for (int i = 1, j = 0; i <= m; i ++ )
    {
        while (j && s[i] != p[j + 1]) j = ne[j];
        if (s[i] == p[j + 1]) j ++ ;//当前位置匹配 继续下一位
        if (j == n)//完全匹配时直接输出
        {
            printf("%d ", i - n);
            j = ne[j];
        }
    }

Trie

int son[N][26], cnt[N], idx;
char str[N];

void insert(char *str)//插入
{
    int p = 0;
    for (int i = 0; str[i]; i ++ )
    {
        int u = str[i] - 'a';
        if (!son[p][u]) son[p][u] = ++ idx;
        p = son[p][u];
    }
    cnt[p] ++ ;
}

int query(char *str)//删除
{
    int p = 0;
    for (int i = 0; str[i]; i ++ )
    {
        int u = str[i] - 'a';
        if (!son[p][u]) return 0;
        p = son[p][u];
    }
    return cnt[p];
}

模拟堆

int h[N],ph[N],hp[N],cnt;
void heap_swap(int a,int b)
{
    swap(ph[hp[a]],ph[hp[b]]);
    swap(hp[a],hp[b]); 
    swap(h[a],h[b]);
}
void up(int u)
{
    while(u/2&&h[u]<h[u/2]){
        heap_swap(u,u/2);
        u=u/2;
    }
}
void down(int l)
{
    int t=l;
    if(l*2<=cnt&&h[l*2]<h[t]) t=l*2;
    if(l*2+1<=cnt&&h[l*2+1]<h[t]) t=l*2+1;
    if(l!=t){
        heap_swap(l,t);
        down(t);
    }
}

哈希

const int N = 200003,inf=0x3f3f3f3f;

int h[N];

int find(int x)
{
    int k=(x % N + N) % N;
    while(h[k]!=inf && h[k] != x)
    {
        k++;
        if(k == N) k=0;
    }
    return k;
}

字符串哈希

    scanf("%s",str+1);//下标从1开始
    P[0]=1;
    for (int i = 1; i <= n; i ++ )
    {
        h[i] = h[i - 1] * p + str[i];
        P[i] = P[i - 1] * p;
    }

 

char str[N];
LL h[N],P[N];

LL hah(int l,int r)
{
    return h[r]-h[l - 1] * P[r - l + 1];
}

 

dijkstra

int pa[N][N],n,m;
int vis[N];
bool st[N];
int  dijkstra()  // 求1号点到n号点的最短路距离
{
    memset(vis, 0x3f, sizeof vis);
    vis[1] = 0;
    for (int i = 0; i < n; i ++ )
    {
        int t=-1;
        for (int j = 0; j < n; j ++ )
        {
            if(!st[j]&&(t==-1||vis[j]<vis[t]))
            t=j;
        }
        st[t]=true;
        for(int j=1;j<=n;j++)
        {
            vis[j]=min(vis[j],vis[t]+pa[t][j]);
        }
    }
    if(vis[n]==0x3f3f3f3f) return -1;
    return vis[n];
}

    memset(pa, 0x3f, sizeof pa);
    for (int i = 0; i < m; i ++ )
    {
        int a,b,c;
        scanf("%d %d %d",&a,&b,&c);
        pa[a][b] = min(pa[a][b],c);
    }

Floyed

void floyd()
{
    for (int k = 1; k <= n; k ++ )
        for (int i = 1; i <= n; i ++ )
            for (int j = 1; j <= n; j ++ )
                d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}

spfa 求最短路

int n, m;
int h[N], w[N], e[N], ne[N], idx;
int dist[N];
bool st[N];

void add(int a, int b, int c)
{
    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}

int spfa()
{
    memset(dist, 0x3f, sizeof dist);
    dist[1] = 0;

    queue<int> q;
    q.push(1);
    st[1] = true;

    while (q.size())
    {
        int t = q.front();
        q.pop();

        st[t] = false;

        for (int i = h[t]; i != -1; i = ne[i])
        {
            int j = e[i];
            if (dist[j] > dist[t] + w[i])
            {
                dist[j] = dist[t] + w[i];
                if (!st[j])
                {
                    q.push(j);
                    st[j] = true;
                }
            }
        }
    }

    return dist[n];
}

spfa 判断负环

int n, m;
int h[N], w[M], e[M], ne[M], idx;
int dist[N], cnt[N];
bool st[N];

void add(int a, int b, int c)
{
    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}

bool spfa()//找到了返回true 否则返回false
{
    queue<int> q;

    for (int i = 1; i <= n; i ++ )
    {
        st[i] = true;
        q.push(i);
    }

    while (q.size())
    {
        int t = q.front();
        q.pop();

        st[t] = false;

        for (int i = h[t]; i != -1; i = ne[i])
        {
            int j = e[i];
            if (dist[j] > dist[t] + w[i])
            {
                dist[j] = dist[t] + w[i];
                cnt[j] = cnt[t] + 1;

                if (cnt[j] >= n) return true;
                if (!st[j])
                {
                    q.push(j);
                    st[j] = true;
                }
            }
        }
    }

    return false;
}

Prim 最小生成树

const int N = 510, INF = 0x3f3f3f3f;

int n, m;
int g[N][N];
int dist[N];
bool st[N];


void add(int a,int b,int c)
{
	g[a][b] = g[b][a] = min(g[a][b], c);
} 


int prim()//最小生成树 
{
    memset(dist, 0x3f, sizeof dist);

    int res = 0;
    for (int i = 0; i < n; i ++ )
    {
        int t = -1;
        for (int j = 1; j <= n; j ++ )
            if (!st[j] && (t == -1 || dist[t] > dist[j]))
                t = j;

        if (i && dist[t] == INF) return INF;

        if (i) res += dist[t];
        st[t] = true;

        for (int j = 1; j <= n; j ++ ) dist[j] = min(dist[j], g[t][j]);
    }

    return res;
}

快速幂

typedef long long LL;

LL qmi(int a, int b, int p)
{
    LL res = 1 % p;
    while (b)
    {
        if (b & 1) res = res * a % p;
        a = a * (LL)a % p;
        b >>= 1;
    }
    return res;
}

哈夫曼树 (优先队列)

int n,x;
priority_queue<int,vector<int>,greater<int>>q;//小根堆
void vpush(int t)//入队
{
    q.push(t);
}
int Max_size() 计算最小值
{
    int res=0;
    while(q.size()>1)
    {
        int a=q.top();q.pop();
        int b=q.top();q.pop();
        res+=a+b;
        vpush(a+b);
    }
    return res;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星辰予曦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值