zoukankan      html  css  js  c++  java
  • [树链剖分]JZOJ 5914 盟主的忧虑

    Description

        江湖由 N 个门派(2≤N≤100,000,编号从 1 到 N)组成,这些门派之间有 N-1 条小道将他们连接起来,每条道路都以“尺”为单位去计量,武林盟主发现任何两个门派都能够直接或者间接通过小道连接。
        虽然整个江湖是可以互相到达的,但是他担心有心怀不轨之徒破坏这个武林的安定,破坏小道,于是武林盟主又秘密地修建了 M 条密道(1≤M≤100,000),但每条小道距离都不超过10亿尺。
        果不其然,最近一个名叫“太吾”的组织意欲破坏武林的小道,请你帮盟主想想办法,如果门派 A 到门派 B 的直连小道被破坏,从 A 走到 B 的所有路径中,经过密道的距离最少是多少? 
     
     

    Input

    第一行数字 N M
    接下来 N-1 行,每行两个整数 A B,表示 A-B 间有一条直连小道
    接下来 M 行,每行三个数字 A B V,表示 A-B 间有一条代价为 V 的密道

    Output

     输出 N-1 行,对应原输入的小道,每个小道被破坏后,最少需要经过多长的密道?如果不存在替换的道路,请输出-1
     
     

    Sample Input

    6 3
    4 1
    1 3
    4 5
    1 2
    6 5
    3 6 8
    2 3 7
    6 4 5

    Sample Output

    8
    7
    5
    7
    5
     

    Data Constraint

    30%数据:N<=300,M<=1000
    50%数据:N<=1000,M<=1000
    70%数据:N<=5000,M<=5000
    对于另外15%的数据点:树是一条链
    100%数据:N,M<=100,000

    分析

    这题显然密道会密道两端到LCA中经过的边的值

    这不就是树链剖分嘛

    写个区间修改走人

    什么?并查集做法?不会

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define rep(i,a,b) for (i=a;i<=b;i++)
    using namespace std;
    const int N=1e5+10;
    struct Node {
        int sz,f,s,seg,top,dep;
    }a[N];
    int scnt,rev[N];
    struct Edge {
        int u,v,nx;
    }g[2*N];
    int cnt,list[N];
    int t[4*N],lz[4*N];
    int mn;
    int n,m;
    
    void Add(int u,int v) {g[++cnt].u=u;g[cnt].v=v;g[cnt].nx=list[u];list[u]=cnt;}
    
    void Dfs1(int x,int f) {
        a[x].f=f;a[x].dep=a[f].dep+1;a[x].sz=1;
        for (int i=list[x];i;i=g[i].nx)
        if (g[i].v!=f) {
           Dfs1(g[i].v,x);
           a[x].sz+=a[g[i].v].sz;
            if (a[g[i].v].sz>a[a[x].s].sz) a[x].s=g[i].v;
        }
    }
    
    void Dfs2(int x,int f) {
        int son=a[x].s;
        if (son) {
            a[son].seg=++scnt;
            rev[scnt]=son;
            a[son].top=a[x].top;
            Dfs2(son,x);
        }
        for (int i=list[x];i;i=g[i].nx)
        if (!a[g[i].v].top) {
            a[g[i].v].seg=++scnt;
            rev[scnt]=g[i].v;
            a[g[i].v].top=g[i].v;
            Dfs2(g[i].v,x);
        }
    }
    
    void Build(int x,int l,int r) {
        if (l==r) {
            t[x]=2147483647;
            return;
        }
        int mid=l+r>>1;
        Build(x<<1,l,mid);Build((x<<1)+1,mid+1,r);
        t[x]=2147483647;
    }
    
    void Pushdown(int x) {
        if (lz[x]) {
            t[x<<1]=lz[x<<1]=min(!lz[x<<1]?2147483647:lz[x<<1],lz[x]);
            t[(x<<1)+1]=lz[(x<<1)+1]=min(!lz[(x<<1)+1]?2147483647:lz[(x<<1)+1],lz[x]);
            lz[x]=0;
        }
    }
    
    void Change_In_Segment(int x,int l,int r,int val,int ll,int rr) {
        if (ll>rr) return;
        if (l>rr||ll>r) return;
        if (ll<=l&&r<=rr) {
            t[x]=min(t[x],val);
            lz[x]=min(!lz[x]?2147483647:lz[x],val);
            return;
        }
        Pushdown(x);
        int mid=l+r>>1;
        if (mid>=ll) Change_In_Segment(x<<1,l,mid,val,ll,rr);
        if (mid<rr) Change_In_Segment((x<<1)+1,mid+1,r,val,ll,rr);
        t[x]=min(t[x<<1],t[(x<<1)+1]);
    }
    
    void Query_In_Segment(int x,int l,int r,int ll,int rr) {
        if (ll>rr) return;
        if (r<ll||l>rr) return;
        if (ll<=l&&r<=rr) {
            mn=min(mn,t[x]);
            return;
        }
        Pushdown(x);
        int mid=l+r>>1;
        if (ll<=mid) Query_In_Segment(x<<1,l,mid,ll,rr);
        if (mid+1<=rr) Query_In_Segment((x<<1)+1,mid+1,r,ll,rr);
    }
    
    void Query_In_Tree(int x,int y) {
        int fx=a[x].top,fy=a[y].top;
        while (fx!=fy) {
            if (a[fx].dep<a[fy].dep) swap(x,y),swap(fx,fy);
            Query_In_Segment(1,1,scnt,a[fx].seg,a[x].seg);
            x=a[fx].f;fx=a[x].top;
        }
        if (a[x].dep>a[y].dep) swap(x,y);
        Query_In_Segment(1,1,scnt,a[x].seg+1,a[y].seg);
    }
    
    void Change_In_Tree(int x,int y,int val) {
        int fx=a[x].top,fy=a[y].top;
        while (fx!=fy) {
            if (a[fx].dep<a[fy].dep) swap(x,y),swap(fx,fy);
            Change_In_Segment(1,1,scnt,val,a[fx].seg,a[x].seg);
            x=a[fx].f;fx=a[x].top;
        }
        if (a[x].dep>a[y].dep) swap(x,y);
        Change_In_Segment(1,1,scnt,val,a[x].seg+1,a[y].seg);
    }
    
    int main() {
        freopen("worry.in","r",stdin);
        freopen("worry.out","w",stdout);
        int i;
        char s[20];
        scanf("%d%d",&n,&m);
        rep(i,1,n-1) {
            int u,v;
            scanf("%d%d",&u,&v);
            Add(u,v);Add(v,u);
        }
        Dfs1(1,0);
        scnt=1;
        a[1].seg=a[1].top=rev[1]=1;
        Dfs2(1,0);
        Build(1,1,scnt);
        for (int i=1;i<=m;i++) {
            int x,y,w;
            scanf("%d%d%d",&x,&y,&w);
            Change_In_Tree(x,y,w);
        }
        for (int i=1;i<=n-1;i++) {
            mn=2147483647;
            Query_In_Tree(g[i*2-1].u,g[i*2-1].v);
            printf("%d
    ",mn==2147483647?-1:mn);
        }
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    UC将发布高性能HTML5游戏引擎XCanvas
    一台晚会3.15拯救不了这些高科技公司
    4G时代更有利于TDD的发展
    【leetcode】Binary Tree Zigzag Level Order Traversal
    四月电商价格战火重燃 服务为决胜之道
    linux sysfs(3)
    ubuntu gedit 中文显示乱码解决方法
    研究人员将Windows Phone 7和Windows Azure推广到平流层的大气污染研究中
    迁移周系列II/II: On Premises 迁移视频
    玩Rock, Paper, Azure Challenge,赢取免费Kinect和Xbox 360!
  • 原文地址:https://www.cnblogs.com/mastervan/p/9818585.html
Copyright © 2011-2022 走看看