社区讨论
为何RE0分,必关n人
P4036[JSOI2008] 火星人参与者 3已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @mj4c6m01
- 此快照首次捕获于
- 2025/12/13 21:33 2 个月前
- 此快照最后确认于
- 2025/12/16 14:50 2 个月前
范浩强Treap
CPP#include <cstdio>
#include <random>
#include <ctime>
#include <iostream>
#include <string>
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int ui;
typedef long double ld;
const int MAXSZ = 1 << 20;
char ch, buf[MAXSZ], *p1, *p2;
int HelloCCF;
#define ge() (p1 == p2 && (p2 = buf + fread(p1 = buf, 1, MAXSZ, stdin), p1 == p2) ? EOF : *p1++)
#define end() putchar('\n')
#define Debug() printf("I Love Furina forever! * %d\n", ++ HelloCCF);
template <typename T_T>
inline void read(T_T &x) {
x = 0;
while (ch < '0' || '9' < ch) ch = ge();
while ('0' <= ch && ch <= '9') {
x = x * 10 + (ch ^ 48);
ch = ge();
}
}
template <typename T_T>
inline void write(T_T x) {
if (x > 9) write(x / 10);
putchar(x % 10 | 48);
}
template <typename T_T>
inline T_T min(T_T a, T_T b) {return a < b ? a : b;}
template <typename T_T>
inline T_T max(T_T a, T_T b) {return a > b ? a : b;}
std::mt19937 mt((ull)time(0) ^ 33241);
const int N = 1e5 + 5, P = 131;
ull tag[N];
std::string CNUM;
struct FHQ {
FHQ *son[2];
char val;
int sz;
ui heap;
ull num;
}*null, *root;
inline void push_up(FHQ *u) {
u -> sz = u -> son[0] -> sz + u -> son[1] -> sz + 1;
u -> num = u -> son[0] -> num * tag[u -> son[1] -> sz + 1] + (u -> val - 'a' + 1) * tag[u -> son[1] -> sz] + u -> son[1] -> num;
}
void build(FHQ *&u, int l, int r) {
if (l > r) return ;
int mid = (l + r) >> 1;
u = new FHQ; *u = {{null, null}, CNUM[mid - 1], 0, mt(), 0};
build(u -> son[0], l, mid - 1);
build(u -> son[1], mid + 1, r);
push_up(u);
}
void split(FHQ *u, int rank, FHQ *&A, FHQ *&B) {
if (u == null) {
A = B = null;
return ;
}
if (u -> son[0] -> sz < rank) {
A = u;
split(u -> son[1], rank - u -> son[0] -> sz - 1, u -> son[1], B);
}
else {
B = u;
split(u -> son[0], rank, A, u -> son[0]);
}
push_up(u);
}
FHQ *merge(FHQ *u, FHQ *v) {
if (u == null) return v;
if (v == null) return u;
if (u -> heap > v -> heap) {
u -> son[1] = merge(u -> son[1], v);
push_up(u);
}
else {
v -> son[0] = merge(u, v -> son[0]);
push_up(v);
}
}
ull get_hash(int l, int r) {
if (l > r) return 1;
FHQ *root1 = null, *root2 = null;
split(root, l - 1, root, root1);
split(root1, r - l + 1, root1, root2);
ull ans = root1 -> num;
root = merge(merge(root, root1), root2);
return ans;
}
void solve(int x, int y) {
if (x > y) std::swap(x, y);
int l = 0, r = root -> sz - y + 1, res = 0;
while (l <= r) {
int mid = l + r >> 1;
ull num1 = get_hash(x, x + mid - 1), num2 = get_hash(y, y + mid - 1);
if (num1 == num2) {
l = mid + 1;
res = mid;
}
else r = mid - 1;
}
std::cout << res << '\n';
}
int main() {
// freopen("Ryan.in", "r", stdin);
// freopen("Ryan.out", "w", stdout);
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
null = new FHQ; *null = {{null, null}, 'a', 0, 0, 0};
root = null;
tag[0] = 1;
for (int i = 1; i <= N - 5; i++) tag[i] = tag[i - 1] * P;
std::cin >> CNUM;
build(root, 1, CNUM.size());
int T; std::cin >> T;
while (T --) {
char type; std::cin >> type;
if (type == 'Q') {
int l, r; std::cin >> l >> r;
solve(l, r);
}
if (type == 'R') {
int l;
char val; std::cin >> l >> val;
FHQ *root1 = null, *root2 = null;
split(root, l - 1, root, root1);
split(root1, 1, root1, root2);
root1 -> val = val;
root = merge(root, merge(root1, root2));
}
if (type == 'I') {
int l;
char val; std::cin >> l >> val;
FHQ *root1 = null, *root2 = new FHQ;
*root2 = {{null, null}, val, 1, mt(), 0};
split(root, l, root, root1);
root = merge(root, merge(root2, root1));
}
}
return 0;
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...