社区讨论

求问

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 条回复,欢迎继续交流。

正在加载回复...