RMQ
Range Minimunm/Maximum Query
f[i][j] : 以i为起点 长度为 的区间的最大值/最小值
最后是用2段区间去拼凑成一个我们要查询的区间,其中会有区间重复,所以使用ST表的前提条件就是要求,重复计算的区间不会对结果有影响,比如求:
最大值、最小值、 & 运算 、|运算 、 gcd
而且,区间是进行预处理的 O(nlogn) ,查询 O(1) , 所以也不能对区间进行修改。
使用线段树也可以对区间进行操作,而且能进行更加复杂的信息维护,但单单进行查询的话,效率是没有ST表高的。
// problem :
#include <bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<int, int> PII;
#define pb push_back
const int N = 1e6 + 5;
typedef unsigned int ui;
unsigned int A, B, C, n, q, f[N][22], a[N];
inline unsigned int rng61() {
A ^= A << 16;
A ^= A >> 5;
A ^= A << 1;
unsigned int t = A;
A = B;
B = C;
C ^= t ^ A;
return C;
}
int main(){
scanf("%d%d%u%u%u", &n, &q, &A, &B, &C);
for (int i = 1; i <= n; i++) {
a[i] = rng61();
f[i][0] = a[i];
}
for (int j = 1; j <= 20; ++j) {
for (int i = 1; i + (1 << j) - 1 <= n; ++i) {
f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
}
}
ui ans = 0;
for (int i = 1; i <= q; i++) {
unsigned int l = rng61() % n + 1, r = rng61() % n + 1;
if (l > r) swap(l, r);
// int x = log2(r - l + 1);
int x = __lg(r - l + 1);
ans ^= max(f[l][x], f[r - (1 <<x) + 1][x]);
}
printf("%u\n", ans);
}
带权并查集
// problem :
#include <bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<int, int> PII;
#define pb push_back
const int N = 2E5 + 5;
int f[N];
ll w[N];
int n, q;
int find(int x) {
if(f[x] == x) return x;
int p = f[x];
find(p); // q
/*
旧的: w[x] : a[x] - a[p]
f[p] = q w[p] : a[p] - a[q]
新的 f[x] = q w[x] : a[x] - a[q] 更新的w[x]
w[x] = a[x] - a[q] = a[x] - a[p] + a[p] - a[q];
*/
w[x] = w[x] + w[p];
return f[x] = f[p];
}
int main(){
scanf("%d %d", &n, &q);
for (int i = 1; i <= n; ++i) {
f[i] = i;
w[i] = 0;
}
ll t = 0;
for (int i = 1; i <= q; ++i) {
int ty, l, r;
scanf("%d %d %d", &ty, &l, &r);
l = (l + t) % n + 1;
r = (r + t) % n + 1;
if(ty == 2) {
if(find(l) != find(r)) continue;
printf("%lld\n", w[l] - w[r]);
t = abs(w[l] - w[r]);
} else {
int x; scanf("%d", &x);
if(find(l) == find(r)) continue;
w[f[l]] = x - w[l] + w[r];
f[f[l]] = f[r];
/*
w[f[l]] = a[f[l]] - a[f[r]]
a[l] - a[r] = x
w[l] = a[l] - a[f[l]], w[r] = a[r] - a[f[r]]
==> w[f[l]] = a[l] - w[l] - (a[r] - w[r])
*/
}
}
return 0;
}