• P4114 Qtree1


    P4114 Qtree1

    题解

    树链剖分的恶心题目

    1.读入边,连边存边

    2.两遍DFS

       第一遍找出每个点的重儿子 son  fa  size

       第二遍更新 dfn  dep  top 

    3.把边权放到深度较大的结点上

    4.线段树建树存边

    5.线段树单点修改,区间查询

    6.树链剖分查询的时候,一开始a,b路径可能是一个v形,然后不断跳跃重链,直到他们在一条重链上,然后两点中深度大的在下面,询问该区间的最大值

    代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<string>
    #include<cstring>
    #include<cstdlib>
    #include<queue>
    
    using namespace std;
    
    inline int read()
    {
        int ans=0;
        char last=' ',ch=getchar();
        while(ch<'0'||ch>'9') last=ch,ch=getchar();
        while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
        if(last=='-') ans=-ans;
        return ans;
    }
    
    const int maxn=1e5+10;
    const int maxm=2e5+10;
    int n,cnt=0;
    struct nod
    {
        int u,v,w;
    }edge[maxm];
    int head[maxn],to[maxm],nxt[maxm];
    inline void addedge(int u,int v)
    {
        to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;
        to[++cnt]=u;nxt[cnt]=head[v];head[v]=cnt;
    }
    
    int tim=0;
    int size[maxn],son[maxn],dfn[maxn],top[maxn],dep[maxn],fa[maxn];
    
    void dfs1(int u,int f)
    {
        fa[u]=f;
        son[u]=0;
        size[u]=1;
        for(int i=head[u],v;i;i=nxt[i])
        {
            if(v=to[i] ,v!=f)
            {
                dfs1(v,u);
                size[u]+=size[v];
                if(size[v]>size[son[u]]) son[u]=v;
            }
        }
    }
    void dfs2(int u,int f)
    {
        tim++;
        dfn[u]=tim;
        dep[u]=dep[f]+1;
        top[u]= (u==son[f] ? top[f] : u);
        if(son[u]!=0) dfs2(son[u],u);
        for(int i=head[u],v;i;i=nxt[i])
        {
            if(v=to[i],v!=f&&v!=son[u])
              dfs2(v,u);
        }
    }
    
    int val[maxn];
    
    int zd[maxn<<2];
    
    void modify(int k,int l,int r,int p,int v)
    {
        if(l==r) { zd[k]=v;return; }
        else
        {
            int mid=(l+r)>>1;
            if(p<=mid) modify(k<<1,l,mid,p,v);
            else modify(k<<1|1,mid+1,r,p,v);
            zd[k]=max(zd[k<<1],zd[k<<1|1]);
        }
    }
    
    int  query(int k,int l,int r,int x,int y)
    {
        if(x>y||y<l||x>r) return 0;
        if(x<=l&&r<=y) return zd[k];
        else
        {
            int mid=(l+r)>>1;
            return max(query(k<<1,l,mid,x,y),
                       query(k<<1|1,mid+1,r,x,y));
        }
    }
    
    int query(int a,int b)
    {
        int ans=0;
        int ta=top[a],tb=top[b];
        while(ta!=tb)
        {
            if(dep[ta]>dep[tb])
              ans=max(ans,query(1,1,n,dfn[ta],dfn[a])),ta=top[a=fa[ta]];
            else 
              ans=max(ans,query(1,1,n,dfn[tb],dfn[b])),tb=top[b=fa[tb]];
        }
        if(dep[a]>dep[b]) swap(a,b);
        return max(ans,query(1,1,n,dfn[a]+1,dfn[b]));
    }
    
    int main()
    {
        n=read();
        for(int i=1;i<n;i++)
        {
            edge[i].u =read();
            edge[i].v =read();
            edge[i].w =read();
            addedge(edge[i].u ,edge[i].v );
        }    
        dfs1(1,0);
        dfs2(1,0);
        for(int i=1;i<n;i++)
        {
            if(dep[edge[i].u] >dep[edge[i].v ]) 
               swap(edge[i].u ,edge[i].v );
            val[edge[i].v ]=edge[i].w ;
        }
        for(int i=1;i<=n;i++)
          modify(1,1,n,dfn[i],val[i]); 
        char s[10];
        while(scanf("%s",s),s[0]!='D')
        {
            int a,b;
            a=read();b=read();
            if(s[0]=='Q') printf("%d
    ",query(a,b));
            if(s[0]=='C') modify(1,1,n,dfn[edge[a].v ],b);
        }
    
        return 0;
    }
  • 相关阅读:
    [Web 前端] CSS 盒子模型,绝对定位和相对定位
    [Android Pro] 跨平台反编译工具 jadx (ubuntu亲测 可用)
    [Web 前端] Jquery 复制元素,并修改属性, 追加到另一个元素后面
    [Web 前端 ] Jquery attr()方法 获取或修改 对象的属性值
    [Web 前端] Jquery实现可直接编辑的表格
    [Web 前端] td长度固定,内容过长,超过部分用省略号代替
    [Network] okhttp3与旧版本okhttp的区别分析
    [Android Pro] AndroidStudio IDE界面插件开发(进阶篇之Editor)
    graph embedding 使用方法
    win10 'make' 不是内部或外部命令
  • 原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/11333216.html
Copyright © 2020-2023  润新知