蓝桥杯模版2

81 阅读2分钟

一、基础算法模板

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

2. 二分查找

// 查找第一个 >=x 的位置(左边界)
int bsearch_left(int arr[], int l, int r, int x) {
    while (l < r) {
        int mid = (l + r) >> 1;
        if (arr[mid] >= x) r = mid;
        else l = mid + 1;
    }
    return l;
}

// 查找最后一个 <=x 的位置(右边界)
int bsearch_right(int arr[], int l, int r, int x) {
    while (l < r) {
        int mid = (l + r + 1) >> 1;
        if (arr[mid] <= x) l = mid;
        else r = mid - 1;
    }
    return l;
}

二、数据结构模板

1. 并查集(路径压缩 + 按秩合并)

const int N = 1e5 + 10;
int p[N], size[N];

int find(int x) {
    if (p[x] != x) p[x] = find(p[x]); // 路径压缩
    return p[x];
}

void merge(int a, int b) {
    a = find(a), b = find(b);
    if (a == b) return;
    if (size[a] > size[b]) swap(a, b); // 按秩合并
    p[a] = b;
    size[b] += size[a];
}

// 初始化
for (int i = 0; i < N; i++) p[i] = i, size[i] = 1;

2. 单调栈(找下一个更大元素)

vector<int> nextGreaterElement(vector<int>& nums) {
    stack<int> stk;
    vector<int> res(nums.size(), -1);
    for (int i = 0; i < nums.size(); i++) {
        while (!stk.empty() && nums[i] > nums[stk.top()]) {
            res[stk.top()] = nums[i];
            stk.pop();
        }
        stk.push(i);
    }
    return res;
}

三、图论模板

1. Dijkstra(最短路-堆优化)

typedef pair<int, int> PII;
const int N = 1e5 + 10;
vector<PII> g[N]; // 邻接表: {to, weight}
int dist[N];
bool st[N];

void dijkstra(int start) {
    memset(dist, 0x3f, sizeof dist);
    priority_queue<PII, vector<PII>, greater<PII>> heap;
    heap.push({0, start});
    dist[start] = 0;

    while (!heap.empty()) {
        auto [d, u] = heap.top();
        heap.pop();
        if (st[u]) continue;
        st[u] = true;
        for (auto [v, w] : g[u]) {
            if (dist[v] > d + w) {
                dist[v] = d + w;
                heap.push({dist[v], v});
            }
        }
    }
}

2. Kruskal(最小生成树)

struct Edge {
    int a, b, w;
    bool operator<(const Edge &e) const { return w < e.w; }
} edges[M]; // M 是边数

int kruskal() {
    sort(edges, edges + m); // 按边权排序
    int res = 0, cnt = 0;
    for (int i = 0; i < m; i++) {
        int a = edges[i].a, b = edges[i].b, w = edges[i].w;
        a = find(a), b = find(b);
        if (a != b) {
            p[a] = b;
            res += w;
            cnt++;
        }
    }
    if (cnt != n - 1) return -1; // 非连通图
    return res;
}

四、动态规划模板

1. 01背包问题

int dp[N]; // dp[j] 表示容量为 j 时的最大价值
int weight[N], value[N];

for (int i = 1; i <= n; i++) {
    for (int j = m; j >= weight[i]; j--) {
        dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
    }
}

2. 最长上升子序列(LIS)

vector<int> a; // 输入序列
vector<int> f; // f[i] 表示长度为 i+1 的 LIS 的最小末尾值

for (int x : a) {
    auto it = lower_bound(f.begin(), f.end(), x);
    if (it == f.end()) f.push_back(x);
    else *it = x;
}
int res = f.size();

五、数论模板

1. 快速幂(求 a^b mod p)

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

2. 欧拉筛(线性筛质数)

const int N = 1e6 + 10;
int primes[N], cnt; // 存储质数
bool st[N]; // st[i] 为 true 表示 i 不是质数

void get_primes(int n) {
    for (int i = 2; i <= n; i++) {
        if (!st[i]) primes[cnt++] = i;
        for (int j = 0; primes[j] <= n / i; j++) {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0) break;
        }
    }
}