模板
Necessary
·
·
个人记录
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;
}