其他分享
首页 > 其他分享> > 力扣竞赛模板

力扣竞赛模板

作者:互联网

Debug

void _debug(ostream& os) { os << '\n'; }
template<typename T, typename... Args> 
void _debug(ostream& os, const T& t, const Args&... args) {
    os << t;
    if (sizeof...(args)) {
        os << ", ";
    }
    _debug(os, args...);
}
#define debug(args...) cerr << #args << " = ", _debug(cout, ##args)

并查集

class UnionFindSet {
public:
    UnionFindSet(int n): components(n), fa(n + 1), sz(n + 1) {
        iota(fa.begin(), fa.end(), 0);
        fill(sz.begin(), sz.end(), 1);
    }
    int find(int x) {
       	return fa[x] == x ? x : fa[x] = find(fa[x]);
    }
    bool merge(int x, int y) {
        x = find(x), y = find(y);
        if (x == y) {
            return false;
        }
        sz[x] += sz[y], fa[y] = x, --components;
        return true;
    }
    bool isConnected(int x, int y) {
        return find(x) == find(y);
    }
    int components;
    vector<int> fa, sz;
};

树状数组

一维

单点修改区间查询

class FenwickTree {
public:
    FenwickTree(int _n): n(_n), c(_n + 1) {}
    FenwickTree(vector<int>& a) {
        n = a.size();
        c.resize(n + 1);
        for (int i = 0; i < n; ++i) {
            add(i + 1, a[i]);
        }
    }
    void add(int i, int k) {
        while (i <= n) {
            c[i] += k;
            i += lowbit(i);
        }
    }
    long long sum(int i) {
        long long res = 0;
        while (i > 0) {
            res += c[i];
            i -= lowbit(i);
        }
        return res;
    }
    long long sum(int l, int r) {
        return sum(r) - sum(l - 1);
    }
    int lowbit(int x) {
        return x & -x;
    }
    int n;
    vector<long long> c;
};

区间修改区间查询

class FenwickTree {
public:
    FenwickTree(int _n): n(_n), a(_n + 1), b(_n + 1) {}
    FenwickTree(vector<int>& c) {
        n = c.size();
        a.resize(n + 1);
        b.resize(n + 1);
        for (int i = 1; i <= n; ++i) {
            int d = (i == 1 ? c[i - 1] : c[i - 1] - c[i - 2]);
            add(a, i, d);
            add(b, i, (i - 1) * d);
        }
    }
    void add(int l, int r, int k) {
        add(a, l, k);
        add(b, l, k * (l - 1));
        add(a, r + 1, -k);
        add(b, r + 1, -k * r);
    }
    void add(vector<long long>& a, int i, int k) {
        while (i <= n) {
            a[i] += k;
            i += lowbit(i);
        }
    }
    long long sum(int l, int r) {
        long long x = (l - 1) * sum(a, l - 1) - sum(b, l - 1);
        long long y = r * sum(a, r) - sum(b, r);
        return y - x;
    }
    long long sum(vector<long long>& a, int i) {
        long long res = 0;
        while (i > 0) {
            res += a[i];
            i -= lowbit(i);
        }
        return res;
    }
    int lowbit(int x) {
        return x & -x;
    }
    int n;
    vector<long long> a, b;
};

二维

class FenwickTree {
public: 
    FenwickTree(int n, int m) : n(n), m(m) {
        t1 = t2 = t3 = t4 = vector<vector<long long>>(n + 1, vector<long long>(m + 1)); 
    }
    FenwickTree(vector<vector<int>>& a) {
        n = a.size(), m = a[0].size();
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= m; ++j) {
                add(i, j, a[i - 1][j - 1]);
            }
        }
    }
    void add(int x, int y, int k) {
        for (int i = x; i <= n; i += lowbit(i)) {
            for (int j = y; j <= m; j += lowbit(j)) {
                t1[i][j] += k;
                t2[i][j] += k * x;
                t3[i][j] += k * y;
                t4[i][j] += k * x * y;
            }
        }
    }
    void add(int x1, int y1, int x2, int y2, int k) {
        add(x1, y1, k);
        add(x1, y2 + 1, -k);
        add(x2 + 1, y1, -k);
        add(x2 + 1, y2 + 1, k);
    }
    long long sum(int x, int y) {
        long long res = 0;
        for (int i = x; i > 0; i -= lowbit(i)) {
            for (int j = y; j > 0; j -= lowbit(j)) {
                res += (x + 1) * (y + 1) * t1[i][j] - (y + 1) * t2[i][j] - (x + 1) * t3[i][j] + t4[i][j];
            }
        }
        return res;
    }
    long long sum(int x1, int y1, int x2, int y2) {
        return sum(x2, y2) - sum(x2, y1 - 1) - sum(x1 - 1, y2) + sum(x1 - 1, y1 - 1);
    }
    int lowbit(int x) {
        return x & -x;
    }
    int n, m;
    vector<vector<long long>> t1, t2, t3, t4;
};

最短路

typedef pair<long long, int> P;
const static long long LINF = (1LL << 60);
vector<long long> dijkstra(vector<vector<pair<int, int>>>& e, int s) {
    vector<long long> d((int)e.size(), LINF);
    priority_queue<P, vector<P>, greater<>> q;
    d[s] = 0LL, q.emplace(0LL, s);
    while (!q.empty()) {
        auto [du, u] = q.top();
        q.pop();
        if (du != d[u]) {
            continue;
        }
        for (auto& [v, w] : e[u]) {
            if (d[u] + w < d[v]) {
                d[v] = d[u] + w;
                q.emplace(d[v], v);
            }
        }
    }
    return d;
}

字符串哈希

const static ULL P = 13331;
typedef unsigned long long ULL;

vector<ULL> h(n + 1), rh(n + 1), p(n + 1);
p[0] = 1;
for (int i = 1; i <= n; ++i) {
    h[i] = h[i - 1] * P + s[i - 1];
    rh[i] = rh[i - 1] * P + s[n - i];
    p[i] = p[i - 1] * P;
}

ULL get(int l, int r, vector<ULL>& hash) {
    return hash[r] - hash[l - 1] * p[r - l + 1];
}
bool isPalindrome(int l, int r, vector<ULL>& hash, vector<ULL> rhash) {
    return get(l, r, h) == get(n - r + 1, n - l + 1, rh); 
}

平衡树

$.order_of_key(k) -> 查找k在集合的排名(从0开始)
$.find_by_order(k) -> 查找集合中第k大(从0开始)
$.lower_bound(k)
$.upper_bound(k)
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;

template<class T> using 
ordered_set = 
	tree<T, null_type, less<T>, rb_tree_tag, 
	tree_order_statistics_node_update>;

template<class T> using 
ordered_multiset = 
	tree<T, null_type, less_equal<T>, rb_tree_tag, 
	tree_order_statistics_node_update>;

template<class T, class U> using 
ordered_map = 
	tree<T, U, less<T>, rb_tree_tag, 
	tree_order_statistics_node_update>;

template<class T, class U> using 
ordered_multimap = 
	tree<T, U, less_equal<T>, rb_tree_tag, 
	tree_order_statistics_node_update>;

01背包(完全背包将V枚举反过来)

最大价值

int bag01(vector<pair<int, int>>& items, int V) {
    vector<int> dp(V + 1);
    for (auto& [v, w]: items) {
        for (int j = V; j >= v; --j) {
            dp[j] = max(dp[j], dp[j - v] + w);
        }
    }
    return dp[V];
}

最大价值方案数

int bag01(vector<pair<int, int>>& items, int V) {
    vector<int> dp(V + 1), cnt(V + 1, 1);
    for (auto& [v, w]: items) {
        for (int j = V; j >= v; --j) {
            if (dp[j] < dp[j - v] + w) {
                cnt[j] = cnt[j - v];
            } else if (dp[j] == dp[j - v] + w) {
                cnt[j] = (cnt[j] + cnt[j - v]) % P;
            }
            dp[j] = max(dp[j], dp[j - v] + w);
        }
    }
    return cnt[V];
}

最大价值并打印字典序最小方案

vector<int> bag01(vector<pair<int, int>>& items, int V) {
    int N = items.size();
    vector<vector<int>> dp(N + 1, vector<int>(V + 1));
    for (int i = N; i >= 1; --i) {
        auto& [v, w] = items[i - 1];
        for (int j = 0; j <= V; ++j) {
            dp[i][j] = dp[i + 1][j];
            if (j >= v) {
                dp[i][j] = max(dp[i][j], dp[i + 1][j - v] + w);
            }
        }
    }
    vector<int> ans;
    for (int i = 1, j = V; i <= N; ++i) {
        auto& [v, w] = items[i - 1];
        if (j >= v && dp[i][j] == dp[i + 1][j - v] + w) {
            ans.push_back(i);
            j -= v;
        }
    }
    return ans;
}

装满时最大\(/\)最小价值

const static int inf = (-1 << 30);
const static int INF = (1 << 30);
int bag01(vector<pair<int, int>>& items, int V) {
    vector<int> dp(V + 1, INF);
    // vector<int> dp(V + 1, inf);
    dp[0] = 0;
    for (auto& [v, w]: items) {
        for (int j = V; j >= v; --j) {
            dp[j] = max(dp[j], dp[j - v] + w);
            // dp[j] = min(dp[j], dp[j - v] + w);
        }
    }
    return (dp[V] != INF ? dp[V] : -1);
}

背包装满时方案数

int bag01(vector<int>& items, int V) {
    vector<int> dp(V + 1);
    dp[0] = 1;
    for (int& v: items) {
        for (int j = V; j >= v; --j) {
            dp[j] = (dp[j] + dp[j - v]) % MOD;
        }
    }
    return dp[V];
}

装满时且最大\(/\)最小价值时方案数

const static int inf = (-1 << 30);
const static int INF = (1 << 30);
int bag01(vector<pair<int, int>>& items, int V) {
    vector<int> dp(V + 1, inf), cnt(V + 1);
    // vector<int> dp(V + 1, INF), cnt(V + 1);
    dp[0] = 0, cnt[0] = 1;
    for (auto& [v, w]: items) {
        for (int j = V; j >= v; --j) {
            if (dp[j] > dp[j - v] + w) {
                cnt[j] = cnt[j - v];
            } else if (dp[j] == dp[j - v] + w) {
                cnt[j] = (cnt[j] + cnt[j - v]) % MOD;
            }
            dp[j] = max(dp[j], dp[j - v] + w);
            // if (dp[j] < dp[j - v] + w) {
            //     cnt[j] = cnt[j - v];
            // } else if (dp[j] == dp[j - v] + w) {
            //     cnt[j] = (cnt[j] + cnt[j - v]) % MOD;
            // }
            // dp[j] = min(dp[j], dp[j - v] + w);
        }
    }
    return cnt[V];
}

分组背包

int bagGroup(vector<vector<pair<int, int>>>& items, int V) {
    vector<int> dp(V + 1);
    for (auto& item : items) {
        for (int j = V; j >= 0; --j) {
            for (auto& [v, w] : item) {
                if (j >= v) {
                    dp[j] = max(dp[j], dp[j - v] + w);
                }
            }
        }
    }
    return dp[V];
}

标签:cnt,竞赛,return,int,items,力扣,vector,模板,dp
来源: https://www.cnblogs.com/stler098/p/16100853.html