社区讨论
求问
P3203[HNOI2010] 弹飞绵羊参与者 2已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mjh74eig
- 此快照首次捕获于
- 2025/12/22 21:32 3 个月前
- 此快照最后确认于
- 2025/12/25 17:45 2 个月前
为什么我的代码在去掉第67行的splay操作后会WA,这个操作不是用来保证复杂度的吗
CPP#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 7;
int n, Q;
int a[N];
struct LCT{
int val[N], sum[N], fa[N], ch[N][2], rev[N], stk[N], top;
void init(){
for(int i = 1; i <= N - 6; i++) val[i] = sum[i] = 1;
}
bool dir(int x){
return ch[fa[x]][1] == x;
}
bool isroot(int x){
return ch[fa[x]][0] != x && ch[fa[x]][1] != x;
}
void push_up(int x){
sum[x] = val[x] + sum[ch[x][0]] + sum[ch[x][1]];
}
void push_rev(int x){
rev[x] ^= 1;
swap(ch[x][0], ch[x][1]);
}
void push_down(int x){
if(rev[x]) push_rev(ch[x][0]), push_rev(ch[x][1]), rev[x] = 0;
}
void rotate(int x){
bool r = dir(x);
int y = fa[x], z = fa[y], w = ch[x][!r];
if(!isroot(y)) ch[z][dir(y)] = x;
ch[x][!r] = y;
ch[y][r] = w;
if(w) fa[w] = y;
fa[x] = z;
fa[y] = x;
push_up(x);
push_up(y);
}
void splay(int x){
int y = x;
stk[++top] = x;
while(!isroot(y)) stk[++top] = y = fa[y];
while(top) push_down(stk[top--]);
while(!isroot(x)){
y = fa[x];
if(!isroot(y)) rotate(dir(x) == dir(y) ? y : x);
rotate(x);
}
push_up(x);
}
void access(int x){
for(int y = 0; x; y = x, x = fa[x]){
splay(x);
ch[x][1] = y;
push_up(x);
}
}
void makeroot(int x){
access(x);
splay(x);
push_rev(x);
}
int findroot(int x){
access(x);
splay(x);
while(ch[x][0]) push_down(x), x = ch[x][0];
splay(x);
return x;
}
void split(int x, int y){
makeroot(x);
access(y);
splay(y);
}
void link(int x, int y){
makeroot(x);
if(findroot(y) == x) return;
fa[x] = y;
}
void cut(int x, int y){
makeroot(x);
if(findroot(y) != x || fa[y] != x || ch[y][0]) return;
fa[y] = ch[x][1] = 0;
push_up(x);
}
}T;
void Task(){
int op;
scanf("%d", &op);
if(op & 1){
int x;
scanf("%d", &x);
x++;
T.split(x, n + 1);
printf("%d\n", T.sum[n + 1] - 1);
}
else{
int x, y;
scanf("%d%d", &x, &y);
x++;
T.cut(x, min(x + a[x], n + 1));
T.link(x, min(x + y, n + 1));
a[x] = y;
}
}
int main(){
T.init();
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%d", &a[i]);
T.link(i, min(i + a[i], n + 1));
}
scanf("%d", &Q);
while(Q--){
Task();
}
return 0;
}
``````
回复
共 1 条回复,欢迎继续交流。
正在加载回复...