10.24T2 树链剖分

2.盟主的忧虑

 (worry)

【问题描述】

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

【输入】

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

【输出】

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

【样例输入】

6 3

4 1

1 3

4 5

1 2

6 5

3 6 8

2 3 7

6 4 5

【样例输出】

8

7

5

7

5

【数据范围与约定】

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

一条密道影响的是连接两点之间的简单路径,所以我们就可以用树链剖分覆盖两点之间的边,维护一下最小值就可以了,查询的时候所有边打包在一起查询就完成了

此题需要扩栈

code:

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstdlib>
  5 #define lc (p<<1)
  6 #define rc (p<<1|1)
  7 #define N 1000006
  8 using namespace std;
  9 const long long inf=99999999999;
 10 struct node{
 11     long long u,v,w;
 12 }e[N];
 13 struct NODE{
 14     int a,b,c;
 15 }q[N];
 16 bool cmp(const NODE&a,const NODE&b){
 17     return a.c>b.c;
 18 }
 19 long long first[N],nxt[N],cnt,Ans[N];
 20 void add(long long u,long long v,long long w){
 21     e[++cnt].u=u;
 22     e[cnt].v=v;
 23     e[cnt].w=w;
 24     nxt[cnt]=first[u];
 25     first[u]=cnt;
 26 }
 27 struct T{
 28     long long l,r,lazy;
 29 }t[N];
 30 void pushnow(long long p,long long v){
 31     t[p].lazy=v;
 32 }
 33 void pushdown(long long p){
 34     if(t[p].lazy!=-1){
 35         pushnow(lc,t[p].lazy);
 36         pushnow(rc,t[p].lazy);
 37         t[p].lazy=-1;
 38     }
 39 }
 40 void build(long long p,long long l,long long r){
 41     t[p].l=l,t[p].r=r;t[p].lazy=-1;
 42     if(l==r)return;
 43     long long mid=l+r>>1;
 44     build(lc,l,mid);
 45     build(rc,mid+1,r);
 46 }
 47 void update(long long p,long long ql,long long qr,long long v){
 48     if(ql<=t[p].l&&t[p].r<=qr){
 49         pushnow(p,v);
 50         return;
 51     }
 52     pushdown(p);
 53     long long mid=t[p].l+t[p].r>>1;
 54     if(ql<=mid)update(lc,ql,qr,v);
 55     if(qr>mid)update(rc,ql,qr,v);
 56 }
 57 long long siz[N],hson[N],dep[N],top[N],num[N],pre[N],tot,fa[N];
 58 void Count(long long p){
 59     if(t[p].l==t[p].r){
 60         Ans[pre[t[p].l]]=t[p].lazy;
 61         return;
 62     }
 63     pushdown(p);
 64     Count(lc);
 65     Count(rc);
 66 }
 67 void dfs1(long long x,long long father){
 68     siz[x]=1,hson[x]=0;fa[x]=father;
 69     for(long long i=first[x];i;i=nxt[i]){
 70         long long v=e[i].v;
 71         if(v==father)continue;
 72         dep[v]=dep[x]+1;
 73         dfs1(v,x);
 74         siz[x]+=siz[v];
 75         if(!hson[x]||siz[hson[x]]<siz[v])hson[x]=v;
 76     }
 77 }
 78 void dfs2(long long x,long long tp,long long father){
 79     top[x]=tp;
 80     pre[num[x]=++tot]=x;
 81     if(hson[x])dfs2(hson[x],tp,x);
 82     for(long long i=first[x];i;i=nxt[i]){
 83         long long v=e[i].v;
 84         if(v==father)continue;
 85         if(v==hson[x])continue;
 86         dfs2(v,v,x);
 87     }
 88 }
 89 long long modify(long long x,long long y,long long v){
 90     while(top[x]!=top[y]){
 91         if(dep[top[y]]>dep[top[x]])swap(x,y);
 92         update(1,num[top[x]],num[x],v);
 93         x=fa[top[x]];
 94     }
 95     if(dep[x]<dep[y])swap(x,y);
 96     if(num[y]+1<=num[x])update(1,num[y]+1,num[x],v);
 97 }
 98 int main(){
 99     int siz=100<<20;//40M
100     __asm__("movl %0,%%esp
"::"r"((char*)malloc(siz)+siz));//windows用这个
101     //__asm__("movq %0,%%rsp
"::"r"((char*)malloc(siz)+siz));//linux用这个
102     long long n,m;
103     cin>>n>>m;
104     for(long long i=1;i<n;i++){
105         long long u,v;
106         cin>>u>>v;
107         add(u,v,0);
108         add(v,u,0);
109     }
110     fa[1]=1;
111     dfs1(1,1);
112     dfs2(1,1,1);
113     build(1,1,tot);
114     for(long long i=1;i<=m;i++){
115         cin>>q[i].a>>q[i].b>>q[i].c;
116     }
117     sort(q+1,q+m+1,cmp);
118     for(int i=1;i<=m;i++){
119         modify(q[i].a,q[i].b,q[i].c);
120     }
121     Count(1);
122     for(long long i=1;i<=cnt;i+=2){
123         long long u=e[i].u,v=e[i].v;
124         if(fa[v]==u)swap(u,v);
125         printf("%d
",Ans[u]);
126     }
127     exit(0);
128     return 0;
129 }

over

原文地址:https://www.cnblogs.com/saionjisekai/p/9846045.html