模版大全!!模板大全!!

模版大全!!模板大全!!

今天无事,整理整理自己写过的模版

以后会经常更新模版哦!

冒泡排序(从小到大)

P1177 【模板】排序

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int n, a[N];
int main(){
    cin >> n;
    for(int i = 0; i < n; i++) cin >> a[i];
    for(int i = 0; i < n; i++){
        for(int j = 0; j < i; j++){
            if(a[i] < a[j]) swap(a[j], a[i]);
        }
    }
    for(int i = 0; i < n; i++) cout << a[i] << ' ';
    return 0;
}

快速幂

P1226 【模板】快速幂

#include <bits/stdc++.h>
#define int long long
using namespace std;
int a, b, MOD;
inline int ksm(int a, int k){
    int ans = 1;
    while(k){
        if(k & 1) ans = ans * a % MOD;
        a = a * a % MOD;
        k >>= 1;
    }
    return ans;
}
inline void solve(){
    cin >> a >> b >> MOD;
    cout << a << '^' << b << " mod " << MOD << '=' << ksm(a, b);
    return ;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    int t = 1;
    // cin >> t;
    while(t--) solve();
    return 0;
}

Nim 游戏

P2197 【模板】Nim 游戏

#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, x;
int ans;
inline void solve(){
    cin >> n >> ans;
    for(int i = 2; i <= n; i++){
        cin >> x;
        ans ^= x;
    }
    if(ans) cout << "Yes\n";
    else cout << "No\n";
    return ;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while(t--) solve();
    return 0;
}

单调栈

P5788 【模板】单调栈

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 3e6 + 5;
int n, a[N], ans[N];
stack<int> st;
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> a[i];
    for(int i = i; i <= n; i++){
        while(!st.empty() && a[st.top()] < a[i]){
            ans[st.top()] = i;
            st.pop();
        }
        st.push(i);
    }
    while(!st.empty()){
        a[st.top()] = 0;
        st.pop();
    }
    for(int i = 1; i <= n; i++) cout << ans[i] << ' ';
	return 0;
}

KMP

P3375 【模板】KMP

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
string s1, s2;
int n, m, nxt[N];
int idx;
int id[N];
char ans[N];
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> s1 >> s2;
    s1 = ' ' + s1, s2 = ' ' + s2, n = s1.size() - 1, m = s2.size() - 1;
    for(int i = 2, j = 0; i <= m; i++){
        while(j && s2[i] != s2[j + 1]) j = nxt[j];
        if(s2[i] == s2[j + 1]) j++;
        nxt[i] = j;
    }
    for(int i = 1, j = 0; i <= n; i++){
        while(j && s1[i] != s2[j + 1]) j = nxt[j];
        if(s1[i] == s2[j + 1]) j++;
        if(j == m) cout << i - m + 1 << '\n';
    }
    for(int i = 1; i <= m; i++) cout << nxt[i] << ' ';
    return 0;
}

裴蜀定理

P4549 【模板】裴蜀定理

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 5;
int n, a[N];
int x, ans;
inline void solve(){
    cin >> n >> ans;
    for(int i = 2; i <= n; i++){
        cin >> x;
        ans = __gcd(ans, x);
    }
    cout << abs(ans);
    return ;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    int t = 1;
    // cin >> t;
    while(t--) solve();
    return 0;
}

线性筛素数

P3383 【模板】线性筛素数

#include <bits/stdc++.h>
using namespace std;
const int N = 1e9 + 5;
int n, q, x;
bool vis[N];
vector<int> g;
void init(){
	vis[1] = 0;
	for(int i = 2; i <= n; i++){
		if(!vis[i]) g.push_back(i); 
		for(auto it : g){
			if(i * it > n) break;
			vis[i * it] = 1;
			if(!(i % it)) break; 
		}
	}
	return ;
}
signed main(){
    ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n >> q;
	init();
	while(q--){
		cin >> x;
		cout << g[x - 1] << '\n';
	}
	return 0;
}

dijstra 最短路

P4779 【模板】单源最短路径(标准版)

#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 1e5 + 5, INF = 0x3f3f3f3f;
int n, m, s, u, v, w, dis[N], vis[N];
priority_queue<PII, vector<PII>, greater<PII>> pq;
vector<PII> g[N];
inline void init(){
    for(int i = 1; i <= n; i++) dis[i] = INF;
    return ;
}
inline void add(int u, int v, int w){
    g[u].push_back({v, w});
    return ;
}
inline void dijkstra(){
    dis[s] = 0;
    pq.push({0, s});
    while(!pq.empty()){
        auto k = pq.top();
        pq.pop();
        if(vis[k.y]) continue;
        vis[k.y] = 1;
        for(auto it : g[k.y]){
            if(dis[it.x] > k.x + it.y){
                dis[it.x] = k.x + it.y;
                pq.push({dis[it.x], it.x});
            }
        }
    }
    return ;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n >> m >> s;
    init();
    while(m--){
        cin >> u >> v >> w;
        add(u, v, w);
    }
    dijkstra();
    for(register int i = 1; i <= n; i++) cout << dis[i] << ' ';
	return 0;
}

单调队列

P1886 滑动窗口 /【模板】单调队列

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
int n, k;
int a[N];
int a1[N], a2[N];
deque<int> q1, q2;
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n >> k;
    for(int i = 1; i <= n; i++) cin >> a[i];
    for(int i = 1; i <= n; i++){
        while(!q1.empty() && a[q1.back()] > a[i]) q1.pop_back();
        while(!q2.empty() && a[q2.back()] < a[i]) q2.pop_back();
        q1.push_back(i), q2.push_back(i);
        if(i >= k){
            while(q1.front() < i - k + 1)q1.pop_front();
            a1[i] = a[q1.front()];
            while(q2.front() < i - k + 1)q2.pop_front();
            a2[i] = a[q2.front()];
        }
        
    }
    for(int i = k; i <= n; i++) cout << a1[i] << ' ';
    cout << '\n';
    for(int i = k; i <= n; i++) cout << a2[i] << ' ';
    return 0;
}

模意义下的乘法逆元

P3811 【模板】模意义下的乘法逆元

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 3e6 + 5;
int n, MOD;
int ans[N];
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    ans[1] = 1;
    cin >> n >> MOD;
    cout << "1\n";
    for(int i = 2; i <= n; i++){
        ans[i] = (MOD - MOD / i) * ans[MOD % i] % MOD;
        cout << ans[i] << '\n';
    }
}

Floyd 最短路

B3647 【模板】Floyd

#include <bits/stdc++.h>
using namespace std;
const int N = 105, INF = 0x3f3f3f3f;
int n, m, u, v, w, dis[N][N];
inline void init(){
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++) dis[i][j] = INF;
        dis[i][i] = 0;
    }
    return ;
}
inline void add(int u, int v, int w){
    dis[u][v] = min(w, dis[u][v]);
    return ;
}
inline void floyed(){
    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 ;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n >> m;
    init();
    while(m--){
        cin >> u >> v >> w;
        add(u, v, w), add(v, u, w);
    }
    floyed();
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++) cout << dis[i][j] << ' ';
        cout << '\n';
    }
    return 0;
}

快速读入

P10815 【模板】快速读入

#include <bits/stdc++.h>
using namespace std;
int n, a, ans;
inline int read(){
    int x = 0, f = 1;
    char c = getchar_unlocked();
    while(c < '0' || c > '9'){
        if(c == '-') f = -1;
        c = getchar_unlocked();
    }
    while(c >= '0' && c <= '9'){
        x = (x << 1) + (x << 3) + (c - '0');
        c = getchar_unlocked ();
    }
    return x * f;
}
signed main(){
    n = read();
    while(n--){
        a = read();
        ans += a;
    }
    cout << ans;
}

传递闭包

B3611 【模板】传递闭包

#include <bits/stdc++.h>
using namespace std;
const int N = 105;
int n, a[N][N];
inline void add(int u, int v){
    a[u][v] = 1;
    return ;
}
inline void floyed(){
    for(int k = 1; k <= n; k++){
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= n; j++) a[i][j] = a[i][j] || (a[i][k] && a[k][j]);
        }
    }
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++) cin >> a[i][j];
    }
    floyed();
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++) cout << a[i][j] << ' ';
        cout << '\n';
    }
    return 0;
}

负环

P3385 【模板】负环

#include <bits/stdc++.h>
using namespace std;
const int N = 2e6 + 5, INF = 0x3f3f3f3f;
int n, m, t, u, v, w, idx, dis[N];
struct node {
	int u, v, w;
}e[N];
inline void init(){
	memset(e, 0, sizeof e);
	idx = 0;
	for(int i = 2; i <= n; i++) dis[i] = INF;
    return ;
}
inline void add(int u, int v, int w){
	e[++idx] = {u, v, w};
    return ;
}
inline bool floyed(){
	for(int i = 1; i < n; i++){
		for(int j = 1; j <= idx; j++){
			if(dis[e[j].u] != INF && dis[e[j].u] + e[j].w < dis[e[j].v]) dis[e[j].v] = dis[e[j].u] + e[j].w;
		}
	}
	for(int i = 1; i <= idx; i++){
		if(dis[e[i].u] == INF || dis[e[i].v] == INF) continue;
		if(dis[e[i].u] + e[i].w < dis[e[i].v]) return 1;
	}
	return 0;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> t;
	while(t--){
		cin >> n >> m;
        init();
		for(int i = 1; i <= m; i++){
			cin >> u >> v >> w;
	        if(w < 0) add(u, v, w);
	        if(w >= 0) add(u, v, w), add(v, u, w);
		}
		if(floyed()) cout << "YES\n";
		else cout << "NO\n";
	}
	return 0;
}

并查集

P3367 【模板】并查集

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 5;
int n, m, z, x, y, f[N];
inline void init(){
    for(int i = 1; i <= n; i++) f[i] = i;
}
inline int find(int x){
    while(x != f[x]) x = f[x] = f[f[x]] = f[f[f[x]]] = f[f[f[f[x]]]] = f[f[f[f[f[x]]]]];
    return x;
}
inline void Union(int x, int y){
    int xx = find(x), yy = find(y);
    if(xx != yy) f[xx] = yy;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n >> m;
    init();
    while(m--){
        cin >> z >> x >> y;
        if(z == 1) Union(x, y);
        else {
            if(find(x) == find(y)) cout << "Y\n";
            else cout << "N\n";
        }
    }
    return 0;
}

普通平衡树

P3369 【模板】普通平衡树

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 5, MOD = 20111119;
struct Treap {
	int d, v, siz, l, r;
}tr[N];
int n, op, v, idx, root;
inline void update(int p){
	tr[p].siz = tr[tr[p].l].siz + tr[tr[p].r].siz + 1;
    return ;
}
inline void rro(int &p){
	int j = tr[p].l;
	tr[p].l = tr[j].r, tr[j].r = p, tr[j].siz=tr[p].siz;
	update(p);
	p = j;
    return ;
}
inline void lro(int &p){
	int j = tr[p].r;
	tr[p].r = tr[j].l, tr[j].l = p, tr[j].siz = tr[p].siz;
	update(p);
	p = j;
    return ;
}
inline void insert(int &p, int v){
	if(!p){
		tr[p = ++idx].siz = 1, tr[p].d = v, tr[p].v = rand() * rand() % MOD;
		return ;
	}
	tr[p].siz++;
	if(v >= tr[p].d) insert(tr[p].r, v);
	else insert(tr[p].l, v);
	if(tr[p].l && tr[p].v > tr[tr[p].l].v) rro(p);
	if(tr[p].r && tr[p].v > tr[tr[p].r].v) lro(p);
	update(p);
    return ;
}
inline void erase(int &p, int v){
	tr[p].siz--;
	if(tr[p].d == v){
		if(!tr[p].l && !tr[p].r) p = 0;
        else if(!tr[p].l || !tr[p].r) p = tr[p].l + tr[p].r;
		else if(tr[tr[p].l].v < tr[tr[p].r].v) rro(p), erase(tr[p].r,v);
		else lro(p), erase(tr[p].l,v);
		return ;
	}
	if(tr[p].d >= v) erase(tr[p].l,v);
	else erase(tr[p].r,v);
	update(p);
    return ;
}
inline int top(int p, int v){
	if(!p) return 0;
	if(v > tr[p].d) return tr[tr[p].l].siz + top(tr[p].r, v) + 1;
	return top(tr[p].l,v);
}
inline int find(int p, int x){
	if(x == tr[tr[p].l].siz + 1) return tr[p].d;
	if(x > tr[tr[p].l].siz + 1) return find(tr[p].r, x - tr[tr[p].l].siz - 1);
	return find(tr[p].l,x);
}
inline int queryprev(int p, int v){
	if(!p) return 0;
	if(tr[p].d >= v) return queryprev(tr[p].l, v);
	int j = queryprev(tr[p].r, v);
	if(!j) return tr[p].d;
	return j;
}
inline int querynext(int p, int v){
	if(!p) return 0;
	if(tr[p].d <= v) return querynext(tr[p].r,v);
	int j = querynext(tr[p].l, v);
	if(!j) return tr[p].d;
	return j;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
	srand(20111119);
	cin >> n;
	for(int i = 1; i <= n; i++){
        cin >> op >> v;
		if(op == 1) insert(root, v);
		if(op == 2) erase(root, v);
		if(op == 3) cout << top(root,v) + 1 << '\n';
		if(op == 4) cout << find(root,v) << '\n';
		if(op == 5) cout << queryprev(root,v) << '\n';
		if(op == 6) cout << querynext(root,v) << '\n';
	}
	return 0;
}

树状数组

P3374 【模板】树状数组 1

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 5e5 + 5;
int n, m, op, x, y, c[N];
inline int lowbit(int x){
    return x & -x;
}
inline void add(int x, int v){
    while(x <= n){
        c[x] += v;
        x += lowbit(x);
    }
}
inline int query(int x){
    int res = 0;
    while(x){
        res += c[x];
        x -= lowbit(x);
    }
    return res;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n >> m;
    for(int i = 1; i <= n; i++){
        cin >> x;
        add(i, x);
    }
    while(m--){
        cin >> op >> x >> y;
        if(op == 1) add(x, y);
        else cout << query(y) - query(x - 1) << '\n';
    }
    return 0;
}

树状数组

P3368 【模板】树状数组 2

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 5e5 + 5;
int n, m, op, x, y, k, a[N], c[N];
inline int lowbit(int x){
    return x & -x;
}
inline void add(int x, int v){
    while(x <= n){
        c[x] += v;
        x += lowbit(x);
    }
    return ;
}
inline int query(int x){
    int res = 0;
    while(x){
        res += c[x];
        x -= lowbit(x);
    }
    return res;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n >> m;
    for(int i = 1; i <= n; i++) cin >> a[i];
    while(m--){
        cin >> op >> x;
        if(op == 2) cout << query(x) + a[x] << '\n';
        else {
            cin >> y >> k;
            add(x, k), add(y + 1, -k);
        }
    }
    return 0;
}

最长公共子序列

P1439 【模板】最长公共子序列

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 5;
int n, idx, a[N], b[N], dp[N], d[N];
unordered_map<int, int> mp;
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> a[i];
        mp[a[i]] = i;
    }
    for(int i = 1; i <= n; i++) cin >> b[i];
    for(int i = 1; i <= n; i++){
        if(mp[b[i]] > d[idx]){
            d[++idx] = mp[b[i]], dp[i] = idx;
            continue;
        }
        int j = lower_bound(d + 1, d + idx + 1, mp[b[i]]) - d;
        d[j] = mp[b[i]], dp[i] = j;
    }
    cout << idx;
    return 0;
}

扫描线 & 矩形面积并

P5490 【模板】扫描线 & 矩形面积并

##include <bits/stdc++.h>
#define int long long
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 1e6 + 5;
int ans, n, idx, xa, xb, ya, yb, a[N << 1], mp[N << 1];
PII tr[N << 2];
struct edge {
    int x, y1, y2, k;
}e[N << 1];
inline bool cmp(edge a, edge b){
    if(a.x != b.x) return a.x < b.x;
    return a.k > b.k;
}
inline void update(int p, int l, int r){
    if(tr[p].x) tr[p].y = a[r + 1] - a[l];
    else tr[p].y = tr[p << 1].y + tr[p << 1 | 1].y;
}
inline void add(int p, int ql, int qr, int l, int r, int k){
    if(ql <= l && r <= qr){
        tr[p].x += k;
        update(p, l, r);
        return ;
    }
    int mid = (l + r) >> 1;
    if(ql <= mid) add(p << 1, ql, qr, l, mid, k);
    if(qr > mid) add(p << 1 | 1, ql, qr, mid + 1, r, k);
    update(p, l, r);
    return ;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> xa >> ya >> xb >> yb;
        e[(i << 1) - 1] = {xa, ya, yb, 1}, e[i << 1] = {xb, ya, yb, -1};
        mp[++idx] = ya, mp[++idx] = yb;
    }
    n <<= 1;
    sort(mp + 1, mp + 1 + n);
    idx = unique(mp + 1, mp + n + 1) - mp - 1;
    for(int i = 1; i <= n; i++){
        int ya = lower_bound(mp + 1, mp + 1 + n, e[i].y1) - mp;
        int yb = lower_bound(mp + 1, mp + 1 + n, e[i].y2) - mp;
        a[ya] = e[i].y1, a[yb] = e[i].y2, e[i].y1 = ya, e[i].y2 = yb;        
    }
    sort(e + 1, e + 1 + n, cmp);
    for(int i = 1; i < n; i++){
        add(1, e[i].y1, e[i].y2 - 1, 1, n, e[i].k);
        ans += tr[1].y * (e[i + 1].x - e[i].x);
    }
    cout << ans;
    return 0;
}

中国剩余定理

P1495 【模板】中国剩余定理(CRT)/ 曹冲养猪

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 15;
int n, a[N], b[N];
int c, ans;
inline int lcm(int a, int b){
	return a * b / __gcd(a, b);
}
inline void solve(){
	cin >> n >> c >> ans;
	for(int i = 1; i < n; i++) cin >> a[i] >> b[i];
	for(int i = 1; i < n; i++){
		while(ans % a[i] != b[i]) ans += c;
		c = lcm(c, a[i]);
	}
	cout << ans;
	return ;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
	int t = 1;
	// cin >> t;
	while(t--) solve();
	return 0;
}

字符串哈希

P3370 【模板】字符串哈希

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e4 + 5, base = 1505, MOD = 0xCCF54188 - 1;
int n, a[N];
string s;
inline int hashing(string s){
    int cnt = 0;
    for(int i = 0; i < s.size(); i++) cnt += (cnt + base * (int)s[i]) % MOD;
    return cnt;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> s;
        a[i] = hashing(s);
    }
    sort(a + 1, a + 1 + n);
    n = unique(a + 1 , a + 1 + n) - a - 1;
    cout << n;
    return 0;
}

最小生成树

P3366 【模板】最小生成树

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 5;
int n, m, u, v, w, cnt, ans, f[N];
struct node {
    int x, y, z;
}g[N];
inline bool cmp(node a, node b){
    return a.z < b.z;
}
inline void add(int i, int u, int v, int w){
    g[i] = {u, v, w};
    return ;
}
inline void init(){
    for(int i = 1; i <= m; i++) f[i] = i;
    return ;
}
inline int find(int x){
    if(f[x] == x) return x;
    return find(f[x]);
}
inline void Union(int x, int y, int z){
    int xx = find(x), yy = find(y);
    if(xx != yy){
        f[xx] = yy, ans += z, cnt++;
    }
    return ;
}
inline void kruskal(){
    sort(g + 1, g + 1 + m, cmp);
    for(int i = 1; i <= m; i++){
        Union(g[i].x, g[i].y, g[i].z);
    }
    return ;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n >> m;
    init();
    for(int i = 1; i <= m; i++){
        cin >> u >> v >> w;
        add(i, u, v, w);
    }
    kruskal();
    if(cnt < n - 1){
        cout << "orz";
        return 0;
    }
    cout << ans;
    return 0;
}

最近公共祖先(LCA)

P3379 【模板】最近公共祖先(LCA)

#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
int n, m, s, u, v;
int idx, f[N], siz[N], dep[N], top[N], dfn[N], heavy[N];
vector<int> g[N];
inline void add(int u, int v){
    g[u].push_back(v);
    return ;
}
inline void dfs1(int u, int fa){
    siz[u] = 1, f[u] = fa, dep[u] = dep[fa] + 1;
    for(auto it : g[u]){
        if(it == fa) continue;
        dfs1(it, u);
        siz[u] += siz[it];
        if(siz[it] > siz[heavy[u]]) heavy[u] = it;
        // cout << it << ' ' << u << '\n';
    }
    return ;
}
inline void dfs2(int u, int tp){
    top[u] = tp, dfn[u] = ++idx;
    if(!heavy[u]) return ;
    dfs2(heavy[u], tp);
    for(auto it : g[u]){
        if(it != f[u] && it != heavy[u]) dfs2(it, it);
    }
    return ;
}
inline int LCA(int u, int v){
    while(top[u] != top[v]){
        if(dep[top[u]] < dep[top[v]]) swap(u, v);
        u = f[top[u]];
    }
    if(dep[u] < dep[v]) swap(u, v);
    return v;
}
inline void solve(){
    cin >> n >> m >> s;
    for(int i = 1; i < n; i++){
        cin >> u >> v;
        add(u, v), add(v, u);
    }
    dfs1(s, 0);
    dfs2(s, s);
    while(m--){
        cin >> u >> v;
        cout << LCA(u, v) << '\n';
    }
    return ;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    int t = 1;
    // cin >> t;
    while(t--) solve();
    return 0;
}

ST 表

P3865 【模板】ST 表 & RMQ 问题

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5, M = 55;
struct node {
    int l, r, maxn;
}tr[N << 2];
int n, m, l, r, tmp, ans, x, y, a[N], arr[N][M];
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
inline void updata(int p){
    tr[p].maxn = max(tr[p << 1].maxn, tr[p << 1 | 1].maxn);
    return ;
}
inline void build(int p, int l, int r){
    tr[p].l = l, tr[p].r = r;
    if(l == r){
        tr[p].maxn = read();
        return ;
    }
    int mid = (l + r) >> 1;
    build(p << 1, l, mid);
    build(p << 1 | 1, mid + 1, r);
    updata(p);
    return ;
}
inline int query(int p, int l, int r){
    if(tr[p].l >= l && tr[p].r <= r) return tr[p].maxn;
    int res = 0, mid = (tr[p].l + tr[p].r) >> 1;
    if(l <= mid) res = max(res, query(p << 1, l, r));
    if(r > mid) res = max(res, query(p << 1 | 1, l, r));
    return res;
}
signed main(){
    n = read(), m = read();
    build(1, 1, n);
    while(m--){
        x = read(), y = read();
        cout << query(1, x, y) << "\n";
    }
    return 0;
}

字典树 Trie

P8306 【模板】字典树 / Trie

#include <bits/stdc++.h>
using namespace std;
const int N = 3e6 + 5, M = 65;
int k, q, n, t[N][M], cnt[N], idx;
string s;
void init(){
	for(int i = 0; i <= idx; i++) for(int j = 0; j <= 122; j++) t[i][j] = 0;
	for(int i = 0; i <= idx; i++) cnt[i] = 0;
	idx = 0;
}
int num(char x){
	if(x >= 'A' && x <= 'Z') return x - 'A';
	else if(x >= 'a' && x <= 'z') return x - 'a' + 26;
	else return x - '0' + 52;
}
void insert(string s){
	int p = 0, l = s.size();
	for(int i = 0; i < l; i++){
		int c = num(s[i]);
		if(!t[p][c]) t[p][c] = ++idx;
		p = t[p][c], cnt[p]++;
	}
}
int find(string s){
	int p = 0, l = s.size();
	for(int i = 0; i < l; i++){
		int c = num(s[i]);
		if(!t[p][c]) return 0;
		p = t[p][c];
	}
	return cnt[p];
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> k;
	while(k--){
		init();
		cin >> n >> q;
		for(int i = 1; i <= n; i++){
			cin >> s;
			insert(s);
		}
		for(int i = 1; i <= q; i++){
			cin >> s;
			cout << find(s) << "\n";
		}
	}
	return 0;
}

哈希表

P11615 【模板】哈希表

#include <bits/stdc++.h>
using namespace std;
mt19937_64 rnd(chrono::steady_clock::now().time_since_epoch().count());
struct Hsh {
	unsigned long long operator ()(const unsigned long long &x) const {
		static const unsigned long long r = rnd();
		return x ^ r;
	}
};
char buf[1 << 23], *p1 = buf, *p2 = buf;
#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
inline unsigned long long rd(){
	unsigned long long x = 0;
	char ch = gc();
	while(!isdigit(ch)) ch = gc();
	while(isdigit(ch)) x = x * 10 + (ch ^ 48), ch = gc();
	return x;
}
signed main(){
    unordered_map<unsigned long long, unsigned long long, Hsh> mp;
    unsigned long long ans = 0;
    int n = rd();
    for(int i = 1; i <= n; i++){
        unsigned long long x = rd();
		ans += mp[x] * i, mp[x] = rd();
	}
    cout << ans;
	return 0;
}

有理数取余

P2613 【模板】有理数取余

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MOD = 19260817;
int x, y, a, b;
inline int getint(){
    int res = 0, ch = getchar();
    while(!isdigit(ch) and ch != EOF) ch = getchar();
    while(isdigit(ch)){
        res = (res << 3) + (res << 1) + (ch - '0');
        res %= MOD;
        ch = getchar();
    }
    return res;
}
inline int exgcd(int &x, int &y, int a, int b){
    if(!b){
        x = 1, y = 0;
        return a;
    }
    int d = exgcd(x, y, b, a % b), w = x;
    x = y, y = w - a / b * y;
    return d;
}
signed main(){
    a = getint(), b = getint();
    if(!b){
        cout << "Angry!";
        return 0;
    }
    exgcd(x, y, b, MOD);
    x = (x % MOD + MOD) % MOD;
    cout << a * x % MOD;
    return 0;
}

线段树 1

P3372 【模板】线段树 1

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 5;
struct node {
    int l, r, sum, tag;
}tr[N << 2];
int n, m, op, x, y, k;
inline void update(int p){
    tr[p].sum = tr[p << 1].sum + tr[p << 1 | 1].sum;
}
inline void downdate(int p){
    if(!tr[p].tag) return ;
    tr[p << 1].sum += tr[p].tag * (tr[p << 1].r - tr[p << 1].l + 1);
    tr[p << 1].tag += tr[p].tag;
    tr[p << 1 | 1].sum += tr[p].tag * (tr[p << 1 | 1].r - tr[p << 1 | 1].l + 1);
    tr[p << 1 | 1].tag += tr[p].tag;
    tr[p].tag = 0;
    return ;
}
inline void build(int p, int l, int r){
    tr[p].l = l, tr[p].r = r;
    if(l == r){
        cin >> tr[p].sum;
        return ;
    }
    int mid = (l + r) >> 1;
    build(p << 1, l, mid);
    build(p << 1 | 1, mid + 1, r);
    update(p);
    return ;
}
inline void add(int p, int l, int r, int v){
    if(l <= tr[p].l && tr[p].r <= r){
        tr[p].sum += (tr[p].r - tr[p].l + 1) * v;
        tr[p].tag += v;
        return ;
    }
    downdate(p);
    int mid = (tr[p].l + tr[p].r) >> 1;
    if(l <= mid) add(p << 1, l, r, v);
    if(mid < r) add(p << 1 | 1, l, r, v);
    update(p);
    return ;
}
inline int query(int p, int l, int r){
    if(l <= tr[p].l && tr[p].r <= r){
        return tr[p].sum;
    }
    downdate(p);
    int ans = 0, mid = (tr[p].l + tr[p].r) >> 1;
    if(l <= mid) ans += query(p << 1, l, r);
    if(mid < r) ans += query(p << 1 | 1, l, r);
    update(p);
    return ans;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
    cin >> n >> m;
    build(1, 1, n);
    while(m--){
        cin >> op >> x >> y;
        if(op == 1){
            cin >> k;
            add(1, x, y, k);
        } else cout << query(1, x, y) << "\n";
    }
    return 0;
}

线段树 2

P3373 【模板】线段树 2

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 5;
struct node {
    int l, r, sum, add, mul;
}tr[N << 2];
int n, q, m, op, x, y, k, a[N];
inline void update(int p){
    tr[p].sum = (tr[p << 1].sum + tr[p << 1 | 1].sum) % m;
    return ;
}
inline void downdate(int p){
    if(tr[p].mul != 1 || tr[p].add != 0){
        tr[p << 1].sum = (tr[p << 1].sum * tr[p].mul + (tr[p << 1].r - tr[p << 1].l + 1) * tr[p].add) % m;
        tr[p << 1].mul = (tr[p << 1].mul * tr[p].mul) % m;
        tr[p << 1].add = (tr[p << 1].add * tr[p].mul + tr[p].add) % m;
        tr[p << 1 | 1].sum = (tr[p << 1 | 1].sum * tr[p].mul + (tr[p << 1 | 1].r - tr[p << 1 | 1].l + 1) * tr[p].add) % m;
        tr[p << 1 | 1].mul = (tr[p << 1 | 1].mul * tr[p].mul) % m;
        tr[p << 1 | 1].add = (tr[p << 1 | 1].add * tr[p].mul + tr[p].add) % m;
        tr[p].mul = 1;
        tr[p].add = 0;
    }
}
inline void build(int p, int l, int r){
    tr[p].l = l, tr[p].r = r;
    tr[p].mul = 1;
    if(l == r){
        tr[p].sum = a[l] % m;
        return ;
    }
    int mid = (l + r) >> 1;
    build(p << 1, l, mid);
    build(p << 1 | 1, mid + 1, r);
    update(p);
    return ;
}
inline void mul(int p, int l, int r, int v){
    if(l <= tr[p].l && tr[p].r <= r){
        tr[p].mul = (tr[p].mul * v) % m;
        tr[p].sum = (tr[p].sum * v) % m;
        tr[p].add = (tr[p].add * v) % m;
        return ;
    }
    downdate(p);
    int mid = (tr[p].l + tr[p].r) >> 1;
    if(mid >= l) mul(p << 1, l, r, v);
    if(mid < r) mul(p << 1 | 1, l, r, v);
    update(p);
    return ;
}
inline void add(int p, int l, int r, int v){
    if(l <= tr[p].l && tr[p].r <= r){
        tr[p].sum = (tr[p].sum + (tr[p].r - tr[p].l + 1) * v) % m;
        tr[p].add = (tr[p].add + v) % m;
        return ;
    }
    downdate(p);
    int mid = (tr[p].l + tr[p].r) >> 1;
    if(mid >= l) add(p << 1, l, r, v);
    if(mid < r) add(p << 1 | 1, l, r, v);
    update(p);
    return ;
}
inline int query(int p, int l, int r){
    if(l <= tr[p].l && tr[p].r <= r){
        return tr[p].sum;
    }
    downdate(p);
    int res = 0;
    int mid = (tr[p].l + tr[p].r) >> 1;
    if(mid >= l) res = (res + query(p << 1, l, r)) % m;
    if(mid < r) res = (res + query(p << 1 | 1, l, r)) % m;
    return res;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n >> q >> m;
    for(int i = 1; i <= n; i++) cin >> a[i];
    build(1, 1, n);
    while(q--){
        cin >> op >> x >> y;
        if(op == 1){
            cin >> k;
            mul(1, x, y, k);
        } else if(op == 2) {
            cin >> k;
            add(1, x, y, k);
        } else cout << query(1, x, y) << "\n";
    }
    return 0;
}

KMP

P3375 【模板】KMP

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
string s1, s2;
int n, m, nxt[N];
int idx;
int id[N];
char ans[N];
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> s1 >> s2;
    s1 = " " + s1, s2 = " " + s2, n = s1.size() - 1, m = s2.size() - 1;
    for(int i = 2, j = 0; i <= m; i++){
        while(j && s2[i] != s2[j + 1]) j = nxt[j];
        if(s2[i] == s2[j + 1]) j++;
        nxt[i] = j;
    }
    for(int i = 1, j = 0; i <= n; i++){
        while(j && s1[i] != s2[j + 1]) j = nxt[j];
        if(s1[i] == s2[j + 1]) j++;
        if(j == m) cout << i - m + 1 << '\n';
    }
    for(int i = 1; i <= m; i++) cout << nxt[i] << ' ';
    return 0;
}

最大二分图匹配

P3386 【模板】二分图最大匹配

#include <bits/stdc++.h>
#define itn int
#define int long long
using namespace std;
const itn N = 505;
int n, m, e, u, v, ans, vis[N], use[N];
vector<int> g[N];
inline void add(int u, int v){
    g[u].push_back(v);
    return ;
}
inline bool find(int x){
    for(auto it : g[x]){
        if(!vis[it]){
            vis[it] = true;
            if((!use[it]) || find(use[it])){
                use[it] = x;
                return 1;
            }
        }
    }
    return 0;
}
inline void init(){
    for(int i = 1; i <= n; i++){
        memset(vis, 0, sizeof vis);
        if(find(i) == 1) ans++;
    }
    return ;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n >> m >> e;
    for(int i = 1; i <= e; i++){
        cin >> u >> v;
        add(u, v);
    }
    init();
    cout << ans;
    return 0;
}
posted @ 2024-08-14 13:09  wayneoi  阅读(122)  评论(0)    收藏  举报