模板

· · 个人记录

ST 表模板


#include <bits/stdc++.h>

#define I ios::sync_with_stdio(false);cin.tie(0)

using ll = long long;

const int N = 1e5 + 5;
const int L = 16; 

using namespace std;

int n, q;

int a[N];
int st[L + 5][N]; // st[i][j] 表示 [i, i + (1 << j) - 1] 的最大值 

int read () {
    int x = 0, f = 1;
    char ch = getchar();
    while(!isdigit(ch)) {
        if(ch == '-') f = -f;
        ch = getchar();
    }
    while(isdigit(ch)) {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

void write (int x) {
    if(x < 0) {
        putchar('-');
        x = -x;
    }
    stack <int> s;
    while(x) {
        s.push(x % 10);
        x /= 10;
    }
    while(!s.empty() ) {
        putchar(s.top() + '0');
        s.pop();
    }
}

int main (void) {

    n = read();
    q = read();

    for(int i = 1; i <= n; i++) a[i] = read();

    for(int i = 1; i <= n; i++) st[0][i] = a[i];

    for(int i = 1; i <= L; i++) {
        for(int j = 1; j + (1 << i) - 1 <= n; j++) {
            st[i][j] = max(st[i - 1][j], st[i - 1][j + (1 << (i - 1))]);
        }
    } 

    while(q--) {

        int l = read();
        int r = read();

        // [l, l + (1 << (log2(r - l + 1)))]  和 [r - (1 << (log2(r - l + 1)), r] 的最大值 

        int k = (int)(log2(r - l + 1));

        cout << max(st[k][l], st[k][r - (1 << k) + 1]) << '\n';
    }

    return 0;
}

变式1:例:区间极差

#include <bits/stdc++.h>

#define I ios::sync_with_stdio(false);cin.tie(0)

using ll = long long;

const int N = 1e5 + 5;
const int L = 16; 

using namespace std;

int n, q;

int a[N];
int st[L + 5][N]; // st[j][i] 表示 [i, i + (1 << j) - 1] 的最大值 
int stMin[L + 5][N];

int read () {
    int x = 0, f = 1;
    char ch = getchar();
    while(!isdigit(ch)) {
        if(ch == '-') f = -f;
        ch = getchar();
    }
    while(isdigit(ch)) {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

void write (int x) {
    if(x < 0) {
        putchar('-');
        x = -x;
    }
    stack <int> s;
    while(x) {
        s.push(x % 10);
        x /= 10;
    }
    while(!s.empty() ) {
        putchar(s.top() + '0');
        s.pop();
    }
}

int main (void) {

    n = read();
    q = read();

    for(int i = 1; i <= n; i++) a[i] = read();

    for(int i = 1; i <= n; i++) st[0][i] = a[i];
    for(int i = 1; i <= n; i++) stMin[0][i] = a[i];

    for(int i = 1; i <= L; i++) {
        for(int j = 1; j + (1 << i) - 1 <= n; j++) {
            st[i][j] = max(st[i - 1][j], st[i - 1][j + (1 << (i - 1))]);
        }
    }

    for(int i = 1; i <= L; i++) {
        for(int j = 1; j  + (1 << i) - 1 <= n; j++) {
            stMin[i][j] = min(stMin[i - 1][j], stMin[i - 1][j + (1 << (i - 1))]);
        }
    }

    while(q--) {

        int l = read();
        int r = read();

        int k = (int)(log2(r - l + 1));

        int maxv = max(st[k][l], st[k][r - (1 << k) + 1]);
        int minv = min(stMin[k][l], stMin[k][r - (1 << k) + 1]);

        cout << maxv - minv << '\n';
    }

    return 0;
}

变式2:区间gcd

#include <bits/stdc++.h>

#define I ios::sync_with_stdio(false);cin.tie(0)

using ll = long long;

const int N = 1e5 + 5;
const int L = 16; 

using namespace std;

int n, q;

int a[N];
int st[L + 5][N]; // st[j][i] 表示 [i, i + (1 << j) - 1] 的区间gcd 
int stMin[L + 5][N];

int read () {
    int x = 0, f = 1;
    char ch = getchar();
    while(!isdigit(ch)) {
        if(ch == '-') f = -f;
        ch = getchar();
    }
    while(isdigit(ch)) {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

void write (int x) {
    if(x < 0) {
        putchar('-');
        x = -x;
    }
    stack <int> s;
    while(x) {
        s.push(x % 10);
        x /= 10;
    }
    while(!s.empty() ) {
        putchar(s.top() + '0');
        s.pop();
    }
}

int main (void) {

    n = read();
    q = read();

    for(int i = 1; i <= n; i++) a[i] = read();

    for(int i = 1; i <= n; i++) st[0][i] = a[i];
    for(int i = 1; i <= n; i++) stMin[0][i] = a[i];

    for(int i = 1; i <= L; i++) {
        for(int j = 1; j + (1 << i) - 1 <= n; j++) {
            st[i][j] = __gcd(st[i - 1][j], st[i - 1][j + (1 << (i - 1))]);
        }
    }

    while(q--) {

        int l = read();
        int r = read();

        int k = (int)(log2(r - l + 1));

        cout << __gcd(st[k][l], st[k][r - (1 << k) + 1]) << '\n';

    }

    return 0;
}

LCA 模板

#pragma GCC optimize(2)
#include <bits/stdc++.h>

#define I ios::sync_with_stdio(false);cin.tie(0)

using ll = long long;

using namespace std;

int n, rt;

map <int, int> fa;

struct E {
    int to, nxt;
}edge[100005];

int f[40005][25];

int dep[40005], etot, head[40005];

void dfs(int u, int fa) {
    f[u][0] = fa;
    for(int i = 1;i <= 19; i++) {
        f[u][i] = f[f[u][i - 1]][i - 1];
    }

    for(int i = head[u]; i != 0; i = edge[i].nxt) {
        int v = edge[i].to;

        if(v == fa) continue;

        dep[v] = dep[u] + 1;

        dfs(v, u);
    }

}

void add (int u, int v) {
    edge[++etot] = {v, head[u]};
    head[u] = etot;
}

int read () {
    int x = 0, f = 1;
    char ch = getchar();
    while(!isdigit(ch)) {
        if(ch == '-') f = -f;
        ch = getchar();
    }
    while(isdigit(ch)) {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

void print (int x) {
    if(x < 0) {
        putchar('-');
        x = -x;
    }
    stack <int> s;
    while(x) {
        s.push(x % 10);
        x /= 10;
    }
    while(!s.empty() ) {
        putchar(s.top() + '0');
        s.pop();
    }
    cout << '\n';
}

int lca(int u, int v) {
    if(dep[u] < dep[v]) swap(u, v);

//  int dif = dep[u] - dep[v];
//  for(int j = 0; j < 20; j++) {
//      if(dif & (1 << j)) u = f[u][j];
//  }

    for(int i = 19; i >= 0; i--) {
        if(f[u][i] && dep[f[u][i]] >= dep[v]) u = f[u][i];
    }

    if(u == v) return u;

    for(int i = 19; i >= 0; i--) {
        if(f[u][i] != f[v][i]) u = f[u][i], v = f[v][i];
    }

    return f[u][0];
}

int main (void) {

    n = read();

    for(int i = 1; i <= n; i++) {
        int u, v;
        u = read();
        v = read();

        if(u == -1) rt = v;
        else if(v == -1) rt = u;
        else add(u, v), add(v, u);

    }

    dep[rt] = 0;

    dfs(rt, 0);

    int m = read();

    while(m--)  {
        int x, y;
        cin >> x >> y;

        int u = lca(x, y);

        if(x == u) cout << 1 << '\n';
        else if(y == u) cout << 2 << '\n';
        else cout << 0 << '\n';
    }

    return 0;
}