社区讨论
求助一个没用的时间戳
CF1416DGraph and Queries参与者 6已保存回复 17
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 17 条
- 当前快照
- 1 份
- 快照标识符
- @lo8vh5ps
- 此快照首次捕获于
- 2023/10/28 01:13 2 年前
- 此快照最后确认于
- 2023/10/28 01:13 2 年前
这道题用线段树维护子树和需要预处理 序,所以我一开始是这么写的:
CPPfor(int i = 1; i <= tot; ++i) if(getf(i) == i) dfs(i);
然后 WA on test 36, 51924th numbers,再后来发现只要 的时间戳初值不为 就能过:
CPP++tm;
for(int i = 1; i <= tot; ++i) if(getf(i) == i) dfs(i);
时间戳的范围是 ,初值 对线段树上的 序按理说没什么影响。而且后面都是在子树上查询,根本不会访问到这个凭空增加的根节点。
请问这是怎么会是呢,还是说本蒟蒻其它地方写挂了,调了一下午 + 一晚上了,有无好哥哥教教,感激不尽 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 条回复,欢迎继续交流。
正在加载回复...