数据过水,请求加强
查看原帖
数据过水,请求加强
565040
Conan15楼主2023/7/21 10:46

在写完题目之后逛了一下讨论区,发现有很多同学反馈了数据过水的情况,例如 siz[u] += siz[v] 写成 siz[u] += v都能过,测试点有相同情况(这点我不清楚)等。

我刚学树剖,A 了这道题之后去写P7735 [NOI2021] 轻重边。因为突发奇想就把 dfs2 函数改了一种写法(当时没有深入想正确性):

正确写法是这样的:

void dfs2(int u, int t) {
    //t为链顶
    dfn[u] = ++tot;
    top[u] = t;
    a[tot] = val[u];    //线段树上是按照dfs序来操作的,因此要把点的编号转化为dfs序编号
    if (son[u]) dfs2(son[u], t);
    for (int i = h[u]; ~i; i = ne[i]) {
        int v = e[i];
        if (v == fa[u]) continue;
        if (v == son[u]) continue;
        dfs2(v, v); //轻儿子要自己开一条重链
    }
}

我改成了:

//换一种写法
void dfs2(int u, int t) {
    //t为链顶
    dfn[u] = ++tot;
    top[u] = t;
    a[tot] = val[u];    //线段树上是按照dfs序来操作的,因此要把点的编号转化为dfs序编号
    for (int i = h[u]; ~i; i = ne[i]) {
        int v = e[i];
        if (v == fa[u]) continue;
        if (v == son[u]) dfs2(son[u], t);	//备注:这里显然是错的!!!
        else dfs2(v, v); //轻儿子要自己开一条重链
    }
}

因为当时比较懒 qwq,所以就没有深入想正确性,直接交到这道题目上验证。

因为交上去之后同样 A了我就没怎么在意,直接用到 轻重边 那题去了。

因为这个错误,我 WA 20 pts,在调试过程中发现 dfs 部分 有问题,就发现了这个写法正确性有误。

树链剖分为了保证重链和子树的 dfs 序连续,要先遍历重儿子再遍历轻儿子,如果像我那样盲改就会出现一部分轻儿子被先遍历的情况。

改成正确的之后,轻重边那题就能过了,但是这题用错误的 dfs 函数仍然可以 AC,希望管理员能对此加强一下数据!

该题正确代码 AC 记录

该题错误代码 AC 记录

备注:刚学树剖,如果我代码还有别的错误请在评论区指出,谢谢!

2023/7/21 10:46
加载中...