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


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

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

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

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

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

  • 相关阅读:
    JavaScript面向对象之类的创建
    VSCode Debug模式下各图标 含义
    Visual Studio icon 含义
    Unity坐标系 左手坐标系 图
    Unity类继承关系 图
    Unity的SendMessage方法
    ONGUI->NGUI->UGUI (Unity UI史)
    Console.WriteLine 不会输出到unity控制台
    Chrome添加Unity本地文档引擎
    Unity "Build failed : Asset is marked as don't save " 解决方案
  • 原文地址:https://www.cnblogs.com/bangdexuanyuan/p/13974638.html
Copyright © 2020-2023  润新知