• 树链剖分边权转化为点权


    现在给出将树链剖分上的边权转化为点权的方法

    也就是将边权转到它下方的点去

    我们通过画图可以发现,这样的话,我们会多算最近公共祖先上方的点

    方法一:先不考虑的多算的部分,还按原来的方法来,在之后消除最近公共祖先的影响

    我们只需要在原来的代码基础上将(query \_ path)改成

    long long query_path(int u,int v)
    {
    	long long ans=0;
    	while(top[u]!=top[v])
    	{
    		if(dep[top[u]]<dep[top[v]]) swap(u,v);
    		ans+=query(1,id[top[u]],id[u]);
    		u=fa[top[u]];
    	}
    	if(dep[u]<dep[v])swap(u,v);
    	ans+=query(1,id[v],id[u]);
    	ans-=query(1,id[v],id[v]);//深度较浅的点id[v]是最近公共祖先
    	return ans;
    }
    
    

    (updatp\_ path)改成

    void update_path(int u,int v){
    	while(top[u]!=top[v])
    	{
    		if(dep[top[u]]<dep[top[v]]) swap(u,v);
    		update(1,id[top[u]],id[u],d);
    		u=fa[top[u]];
    	}
    	if(dep[u]<dep[v])swap(u,v);
    	update(1,id[v],id[u],d);
    	update(1,id[v],id[v],-d);
    } 
    

    方法二

    直接在修改和查询操作的时候,不将最近公共祖先算进去就行

    这个是由我们的(dfs)序决定的

    long long query_path(int u,int v)
    {
    	long long ans=0;
    	while(top[u]!=top[v])
    	{
    		if(dep[top[u]]<dep[top[v]]) swap(u,v);
    		ans+=query(1,id[top[u]],id[u]);
    		u=fa[top[u]];
    	}
    	if(dep[u]<dep[v])swap(u,v);
    	ans+=query(1,id[v]+1,id[u]);
    	return ans;
    }
    

    (update \_ path)

    void update_path(int u,int v){
    	while(top[u]!=top[v])
    	{
    		if(dep[top[u]]<dep[top[v]]) swap(u,v);
    		update(1,id[top[u]],id[u],d);
    		u=fa[top[u]];
    	}
    	if(dep[u]<dep[v])swap(u,v);
    	update(1,id[v]+1,id[u],d);
    } 
    

    注意

    在递归的时候记得检查一下我们在递归到最底层的时候,我们是否return 不然会一直递归下去,发生段错误

  • 相关阅读:
    maven 父子模块保持相同
    Maven deploy时排除指定的某个module
    源码,反码,补码
    Java日志之Slf4j,Log4J,logback原理总结
    Git Bash设置代理
    分享2个分布式锁
    二叉树的遍历记忆方法
    MySQL百万级数据分页查询及优化
    eclipse无法访问sun.misc.Unsafe类的解决办法
    Spring学习日志之纯Java配置的MVC框架搭建
  • 原文地址:https://www.cnblogs.com/bangdexuanyuan/p/13974638.html
Copyright © 2020-2023  润新知