关于第一次 dfs 的疑问

P3384 【模板】重链剖分/树链剖分

UMS2 @ 2024-02-27 10:01:07

几个月前我是这么写的,能过R118322717。

void dfs(int d,int f,int u){
    dep[u]=d;
    fa[u]=f;
    size[u]=1;
    int soc=-1;

    for(int i=h[u];i;i=e[i].u){
        int v=e[i].v;
        if(v!=f){
            dfs(d+1,u,v);
            size[u]+=size[v];
            if(size[v]>soc){
                son[u]=v;
                soc=size[v];
            }
        }
    }
}

最近复习,想优化一下,写成这样。

void dfs(int u){
    dep[u]=dep[fa[u]]+1;
    size[u]=1;

    for(int i=h[u];i;i=e[i].u){
        int v=e[i].v;
        if(v!=fa[u]){
            fa[v]=u;
            dfs(v);
            size[u]+=size[v];
            if(size[v]>son[u])son[u]=v;
        }
    }
}

却直接 T 了 3 个点,R148486659。

测试了一下,发现是把 soc 删掉之后 T 的,即使只是把 soc 放在 for() 里都会慢将近 200ms,R148486941。

这是为啥,访问数组比访问变量更慢吗?


by UMS2 @ 2024-02-27 10:08:28

不是,我第二版代码比较重儿子写错是怎么过七个点的。


by UMS2 @ 2024-02-27 10:13:14

修改后重测一边,仍然相差 50ms,R148487882。


by 大眼仔Happy @ 2024-02-27 10:31:48

@UMS2 50ms 评测机波动吧


by UMS2 @ 2024-02-27 10:59:08

现在又试了几次,还是在 950ms 左右。可能就是访问数组比访问变量慢一点,删掉变量本来就是想省下来反复开变量的浪费。


by UMS2 @ 2024-02-27 11:00:38

附记录R148491111/R148491127


by Azote @ 2024-02-29 14:37:27

@UMS2

size[v] > son[u]

你在写什么(


by Azote @ 2024-02-29 14:43:47

实际应该不差这点时间(


by UMS2 @ 2024-02-29 15:42:06

@Azote 刚发出去就发现了...不过这个不影响正确性,只是没有了重链的性质复杂度飙升。


by Azote @ 2024-02-29 16:12:06

@UMS2 对于开变量的时间我只能说相信O2,最后基本连常数都算不上。

有时候时间有差别可能是因为运行方式,比如二维数组n,m互换会导致出现时间差别,再比如for(;;)比while(1)快是因为for(;;)运行时不需要比较1是否为真,基本是基础运行方式的问题。

你这个开变量更快我认为是因为反复开反复使用进缓存了,或者就是波动了(


|