专栏文章

模板

个人记录参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@min7x4zw
此快照首次捕获于
2025/12/01 22:01
3 个月前
此快照最后确认于
2025/12/01 22:01
3 个月前
查看原文

STST 表模板

CPP

#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:例:区间极差

CPP
#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

CPP
#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;
}

LCALCA 模板

CPP
#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;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...