算法模板整理

//基础算法课

1.1快速排序

1.1.1模板 —— 模板题 AcWing 785. 快速排序

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);

}

1.1.2  Acwing785.快速排序

#include <iostream>

#include <cstdio>

#include <algorithm>

using namespace std;

const int N=1000010;

int n;

int q[N];

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 main()

{

    cin>>n;

    for(int i=0;i<n;i++) scanf("%d",&q[i]);

    quick_sort(q,0,n-1);

    for(int i=0;i<n;i++) printf("%d ",q[i]);

    return 0;

}

1.1.2  Acwing786.第K个数

#include <iostream>

#include <cstdio>

using namespace std;

const int N=1e6+10;

int q[N];

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 main()

{

    int n,k;

    cin>>n>>k;

    for(int i=0;i<n;i++)

        scanf("%d",&q[i]);

    quick_sort(q,0,n-1);

    printf("%d",q[k-1]);

    return 0;

}

1.2归并排序

1.2.1 模板 —— 模板题 AcWing 787. 归并排序

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];

}

1.3 二分

1.3.1模板:整数二分算法模板 —— 模板题 AcWing 789. 数的范围

bool check(int x) { ... } // 检查x是否满足某种性质



// 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用:

int bsearch_1(int l, int r)

{

    while (l < r)

    {

        int mid = l + r >> 1;

        if (check(mid)) r = mid;    // check()判断mid是否满足性质

        else l = mid + 1;

    }

    return l;

}

// 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用:

int bsearch_2(int l, int r)

{

    while (l < r)

    {

        int mid = l + r + 1 >> 1;

        if (check(mid)) l = mid;

        else r = mid - 1;

    }

    return l;

}

1.3.2 模板:浮点数二分算法模板 —— 模板题 AcWing 790. 数的三次方根

bool check(double x) { ... } // 检查x是否满足某种性质



double bsearch_3(double l, double r)

{

    const double eps = 1e-6;   // eps 表示精度,取决于题目对精度的要求

    while (r - l > eps)

    {

        double mid = (l + r) / 2;

        if (check(mid)) r = mid;

        else l = mid;

    }

    return l;

}

//1.4 高精度

//模板:高精度加法 —— 模板题 AcWing 791. 高精度加法

/*

// C = A + B, A >= 0, B >= 0

vector<int> add(vector<int> &A, vector<int> &B)

{

    if (A.size() < B.size()) return add(B, A);

    vector<int> C;

    int t = 0;

    for (int i = 0; i < A.size(); i ++ )

    {

        t += A[i];

        if (i < B.size()) t += B[i];

        C.push_back(t % 10);

        t /= 10;

    }

    if (t) C.push_back(t);

    return C;

}

*/

//模板:高精度减法 —— 模板题 AcWing 792. 高精度减法

/*

// C = A - B, 满足A >= B, A >= 0, B >= 0

vector<int> sub(vector<int> &A, vector<int> &B)

{

    vector<int> C;

    for (int i = 0, t = 0; i < A.size(); i ++ )

    {

        t = A[i] - t;

        if (i < B.size()) t -= B[i];

        C.push_back((t + 10) % 10);

        if (t < 0) t = 1;

        else t = 0;

    }

    while (C.size() > 1 && C.back() == 0) C.pop_back();

    return C;

}

*/

//模板:高精度乘低精度 —— 模板题 AcWing 793. 高精度乘法

/*

// C = A * b, A >= 0, b >= 0

vector<int> mul(vector<int> &A, int b)

{

    vector<int> C;

    int t = 0;

    for (int i = 0; i < A.size() || t; i ++ )

    {

        if (i < A.size()) t += A[i] * b;

        C.push_back(t % 10);

        t /= 10;

    }

    while (C.size() > 1 && C.back() == 0) C.pop_back();

    return C;

}

*/

//模板:高精度除以低精度 —— 模板题 AcWing 794. 高精度除法

/*

// A / b = C ... r, A >= 0, b > 0

vector<int> div(vector<int> &A, int b, int &r)

{

    vector<int> C;

    r = 0;

    for (int i = A.size() - 1; i >= 0; i -- )

    {

        r = r * 10 + A[i];

        C.push_back(r / b);

        r %= b;

    }

    reverse(C.begin(), C.end());

    while (C.size() > 1 && C.back() == 0) C.pop_back();

    return C;

}

*/

//1.5 前缀和

//模板:一维前缀和 —— 模板题 AcWing 795. 前缀和

/*

S[i] = a[1] + a[2] + ... a[i]

a[l] + ... + a[r] = S[r] - S[l - 1]

二维前缀和 —— 模板题 AcWing 796. 子矩阵的和

S[i, j] = 第i行j列格子左上部分所有元素的和

以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵的和为:

S[x2, y2] - S[x1 - 1, y2] - S[x2, y1 - 1] + S[x1 - 1, y1 - 1]

一维差分 —— 模板题 AcWing 797. 差分

给区间[l, r]中的每个数加上c:B[l] += c, B[r + 1] -= c

二维差分 —— 模板题 AcWing 798. 差分矩阵

给以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵中的所有元素加上c:

S[x1, y1] += c, S[x2 + 1, y1] -= c, S[x1, y2 + 1] -= c, S[x2 + 1, y2 + 1] += c

*/

//1.6 位运算

//1.6.1 模板:模板题 AcWing 801. 二进制中1的个数

/*

求n的第k位数字: n >> k & 1

返回n的最后一位1:lowbit(n) = n & -n

*/

//1.7 双指针算法

//1.7.1模板:模板题 AcWIng 799. 最长连续不重复子序列, AcWing 800. 数组元素的目标和

/*

for (int i = 0, j = 0; i < n; i ++ )

{

    while (j < i && check(i, j)) j ++ ;

    // 具体问题的逻辑

}

常见问题分类:

    (1) 对于一个序列,用两个指针维护一段区间

    (2) 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作

*/

   

//1.8 离散化

//1.8.1模板:模板题 AcWing 802. 区间和

/*

vector<int> alls; // 存储所有待离散化的值

sort(alls.begin(), alls.end()); // 将所有值排序

alls.erase(unique(alls.begin(), alls.end()), alls.end());   // 去掉重复元素

// 二分求出x对应的离散化的值

int find(int x) // 找到第一个大于等于x的位置

{

    int l = 0, r = alls.size() - 1;

    while (l < r)

    {

        int mid = l + r >> 1;

        if (alls[mid] >= x) r = mid;

        else l = mid + 1;

    }

    return r + 1; // 映射到1, 2, ...n

}

*/

//1.9 区间合并

//1.9.1模板:模板题 AcWing 803. 区间合并

/*

// 将所有存在交集的区间合并

void merge(vector<PII> &segs)

{

    vector<PII> res;

    sort(segs.begin(), segs.end());

    int st = -2e9, ed = -2e9;

    for (auto seg : segs)

        if (ed < seg.first)

        {

            if (st != -2e9) res.push_back({st, ed});

            st = seg.first, ed = seg.second;

        }

        else ed = max(ed, seg.second);

    if (st != -2e9) res.push_back({st, ed});

    segs = res;

}

*/

2.数据结构

2.1 单链表

2.1.1 模板—— 模板题 AcWing 826. 单链表

// head存储链表头,e[]存储节点的值,ne[]存储节点的next指针,idx表示当前用到了哪个节点

int head, e[N], ne[N], idx;

// 初始化

void init()

{

    head = -1;

    idx = 0;

}

// 在链表头插入一个数a

void insert(int a)

{

    e[idx] = a, ne[idx] = head, head = idx ++ ;

}

// 将头结点删除,需要保证头结点存在

void remove()

{

    head = ne[head];

}

AcWing 826. 单链表

2.2 双链表

2.2.1 模板

2.2.2  AcWing 827. 双链表

2.3 栈

2.3.1 模板

2.3.2 AcWing 828. 模拟栈

2.3.3 AcWing 3302. 表达式求值

2.4 队列

2.4.1 模板

2.4.2 AcWing 829. 模拟队列

2.5 单调栈

2.5.1 模板

2.5.2 AcWing 830. 单调栈

2.6 单调队列

2.6.1 模板

2.6.2 AcWing 154. 滑动窗口

2.7 KMP

2.7.1 模板

2.7.2 AcWing 831. KMP字符串

2.8 Trie

2.8.1 模板

2.8.2 AcWing 835. Trie字符串统计

2.8.3 AcWing 143. 最大异或对

2.9 并查集

2.9.1 模板

2.9.2 AcWing 836. 合并集合

2.9.3 AcWing 837. 连通块中点的数量

2.9.4 AcWing 240. 食物链

2.10 堆

2.10.1 模板

2.10.2 AcWing 838. 堆排序

2.10.3 AcWing 839. 模拟堆

2.11 哈希表

2.11.1 模板

2.11 .2 AcWing 840. 模拟散列表

2.11.3 AcWing 841. 字符串哈希

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值