zoukankan      html  css  js  c++  java
  • 树链剖分边权转化为点权

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

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

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

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

    我们只需要在原来的代码基础上将(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 不然会一直递归下去,发生段错误

  • 相关阅读:
    Scrum会议5
    小组项目alpha发布的评价
    第二阶段冲刺记录三
    第二阶段冲刺记录二
    第13周学习进度
    第二阶段冲刺记录1
    《人月神话》阅读笔记01
    第12周学习进度
    意见汇总
    双人结对,四则运算(三阶段)
  • 原文地址:https://www.cnblogs.com/bangdexuanyuan/p/13974638.html
Copyright © 2011-2022 走看看