社区讨论

求助一个没用的时间戳

CF1416DGraph and Queries参与者 6已保存回复 17

讨论操作

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

当前回复
17 条
当前快照
1 份
快照标识符
@lo8vh5ps
此快照首次捕获于
2023/10/28 01:13
2 年前
此快照最后确认于
2023/10/28 01:13
2 年前
查看原帖
这道题用线段树维护子树和需要预处理 dfndfn 序,所以我一开始是这么写的:
CPP
for(int i = 1; i <= tot; ++i) if(getf(i) == i) dfs(i);
然后 WA on test 36, 51924th numbers,再后来发现只要 dfndfn 的时间戳初值不为 00 就能过:
CPP
++tm;
for(int i = 1; i <= tot; ++i) if(getf(i) == i) dfs(i);
时间戳的范围是 1tot1\sim tot,初值 +1+1 对线段树上的 dfndfn 序按理说没什么影响。而且后面都是在子树上查询,根本不会访问到这个凭空增加的根节点。
请问这是怎么会是呢,还是说本蒟蒻其它地方写挂了,调了一下午 + 一晚上了,有无好哥哥教教,感激不尽 QAQ。
下面是通过的代码:
CPP
#include <iostream>
#include <cstdio>

#define maxn 500005
#define ls (x << 1)
#define rs (x << 1 | 1)

using namespace std;

inline int read(){
	int x = 0, flag = 1;
	char ch = getchar();
	while(ch < '0' || ch > '9'){
		if(ch == '-') flag = -1;
		ch = getchar();
	}
	while(ch >= '0' && ch <= '9'){
		x = (x << 3) + (x << 1) + ch - '0';
		ch = getchar();
	}
	return x * flag;
}

int n, m, Q, tot, p[maxn], fade[maxn];
int rt[maxn], s[maxn][2];
int tm, siz[maxn], dfn[maxn];

struct edge{
	int u, v;
}e[maxn];

struct que{
	int o, x;
}q[maxn];

struct point{
	int mx, id;
}t[maxn << 2];

point pmax(point x, point y){
	if(x.mx > y.mx) return x;
	else return y;
}

int getf(int x){
	if(rt[x] == x) return x;
	return rt[x] = getf(rt[x]);
}

void adopt(int x, int y){
	int fx = getf(x), fy = getf(y);
	if(fx == fy) return;
	++tot;
	rt[tot] = tot;
	rt[fx] = rt[fy] = tot;
	s[tot][0] = fx, s[tot][1] = fy;
	return;
}

void dfs(int u){
	dfn[u] = ++tm;
	siz[u] = 1;
	for(int i = 0; i <= 1; ++i){
		int v = s[u][i];
		if(!v) continue; 
		dfs(v);
		siz[u] += siz[v];
	}
	return;
}

void change(int x, int l, int r, int ppp, int qqq){
	if(l == r){
		t[x].id = l;
		t[x].mx = qqq;
		return;
	}
	int mid = (l + r) >> 1;
	if(ppp <= mid) change(ls, l, mid, ppp, qqq);
	else change(rs, mid + 1, r, ppp, qqq);
	t[x] = pmax(t[ls], t[rs]);
	return;
}

point ask(int x, int l, int r, int lll, int rrr){
	if(l > rrr || r < lll) return (point){0, 0};
	if(l >= lll && r <= rrr) return t[x];
	int mid = (l + r) >> 1;
	return pmax(ask(ls, l, mid, lll, rrr), ask(rs, mid + 1, r, lll, rrr));
}

int main(){
	n = read(), m = read(), Q = read(), tot = n;
	for(int i = 1; i <= n; ++i) p[i] = read(), rt[i] = i;
	for(int i = 1; i <= m; ++i)
		e[i].u = read(), e[i].v = read();
	for(int i = 1; i <= Q; ++i){
		q[i].o = read(), q[i].x = read();
		if(q[i].o == 2) fade[q[i].x] = 1;
	}
	for(int i = 1; i <= m; ++i)
		if(!fade[i]) adopt(e[i].u, e[i].v);
	for(int i = Q; i; --i)
		if(q[i].o == 2) adopt(e[q[i].x].u, e[q[i].x].v);
		else q[i].x = getf(q[i].x);

//	错误的代码: 
//	for(int i = 1; i <= tot; ++i) if(getf(i) == i) dfs(i);

//	正确的代码: 
	++tm;
	for(int i = 1; i <= tot; ++i) if(getf(i) == i) dfs(i);
 
	for(int i = 1; i <= n; ++i) change(1, 1, tm, dfn[i], p[i]);
	for(int i = 1; i <= Q; ++i)
		if(q[i].o == 1){
			int z = q[i].x;
			point ans = ask(1, 1, tm, dfn[z], dfn[z] + siz[z] - 1);
			printf("%d\n", ans.mx);
			change(1, 1, tm, ans.id, 0);
		}
		
//		cout << tm << ' ' << tot << endl;
	return 0;
}

回复

17 条回复,欢迎继续交流。

正在加载回复...