码迷,mamicode.com
首页 > 其他好文 > 详细

Luogu4556 雨天的尾巴 树上差分、线段树合并

时间:2018-12-05 12:23:32      阅读:254      评论:0      收藏:0      [点我收藏+]

标签:style   16px   get   size   line   pac   pen   bsp   head   

传送门


 

一个套路题……

树上差分+线段树合并即可

注意一个细节:$pushup$的时候如果最大值为$0$一定要把最大值对应的答案也设为$0$,否则会$WA$第二个点

另外如果这道题空限变小了请不要交这份代码,因为这份代码没有卡空间。。。

  1 #include<bits/stdc++.h>
  2 #define mid ((l + r) >> 1)
  3 //This code is written by Itst
  4 using namespace std;
  5 
  6 inline int read(){
  7     int a = 0;
  8     bool f = 0;
  9     char c = getchar();
 10     while(c != EOF && !isdigit(c)){
 11         if(c == -)
 12             f = 1;
 13         c = getchar();
 14     }
 15     while(c != EOF && isdigit(c)){
 16         a = (a << 3) + (a << 1) + (c ^ 0);
 17         c = getchar();
 18     }
 19     return f ? -a : a;
 20 }
 21 
 22 const int MAXN = 100000;
 23 struct node{
 24     int l , r , maxN , maxInd;
 25 }Tree[MAXN * 80];
 26 struct Edge{
 27     int end , upEd;
 28 }Ed[MAXN + 10 << 1];
 29 int root[MAXN + 10] , head[MAXN + 10] , jump[MAXN + 10][21] , dep[MAXN + 10] , ans[MAXN + 10] , cntNode , cntEd , N , M;
 30 
 31 inline void addEd(int a , int b){
 32     Ed[++cntEd].end = b;
 33     Ed[cntEd].upEd = head[a];
 34     head[a] = cntEd;
 35 }
 36 
 37 void dfs(int now , int fa){
 38     jump[now][0] = fa;
 39     dep[now] = dep[fa] + 1;
 40     for(int i = 1 ; jump[now][i - 1] ; ++i)
 41         jump[now][i] = jump[jump[now][i - 1]][i - 1];
 42     for(int i = head[now] ; i ; i = Ed[i].upEd)
 43         if(Ed[i].end != fa)
 44             dfs(Ed[i].end , now);
 45 }
 46 
 47 inline int LCA(int x , int y){
 48     if(dep[x] < dep[y])
 49         swap(x , y);
 50     for(int i = 19 ; i >= 0 ; --i)
 51         if(dep[x] - (1 << i) >= dep[y])
 52             x = jump[x][i];
 53     if(x == y)
 54         return x;
 55     for(int i = 19 ; i >= 0 ; --i)
 56         if(jump[x][i] != jump[y][i]){
 57             x = jump[x][i];
 58             y = jump[y][i];
 59         }
 60     return jump[x][0];
 61 }
 62 
 63 inline void pushup(int now){
 64     if(Tree[Tree[now].l].maxN >= Tree[Tree[now].r].maxN){
 65         Tree[now].maxN = Tree[Tree[now].l].maxN;
 66         Tree[now].maxInd = Tree[Tree[now].l].maxInd;
 67     }
 68     else{
 69         Tree[now].maxN = Tree[Tree[now].r].maxN;
 70         Tree[now].maxInd = Tree[Tree[now].r].maxInd;
 71     }
 72     if(!Tree[now].maxN)
 73         Tree[now].maxInd = 0;
 74 }
 75 
 76 void insert(int& now , int l , int r , int tar , int num){
 77     if(!now)
 78         now = ++cntNode;
 79     if(l == r){
 80         Tree[now].maxN += num;
 81         Tree[now].maxInd = tar;
 82         return;
 83     }
 84     if(mid >= tar)
 85         insert(Tree[now].l , l , mid , tar , num);
 86     else
 87         insert(Tree[now].r , mid + 1 , r , tar , num);
 88     pushup(now);
 89 }
 90 
 91 int merge(int p , int q , int l , int r){
 92     if(!p)
 93         return q;
 94     if(!q)
 95         return p;
 96     if(l == r){
 97         Tree[p].maxN += Tree[q].maxN;
 98         return p;
 99     }
100     Tree[p].l = merge(Tree[p].l , Tree[q].l , l , mid);
101     Tree[p].r = merge(Tree[p].r , Tree[q].r , mid + 1 , r);
102     pushup(p);
103     return p;
104 }
105 
106 void getAns(int now){
107     for(int i = head[now] ; i ; i = Ed[i].upEd)
108         if(Ed[i].end != jump[now][0]){
109             getAns(Ed[i].end);
110             root[now] = merge(root[now] , root[Ed[i].end] , 1 , MAXN);
111         }
112     ans[now] = Tree[root[now]].maxInd;
113 }
114 
115 int main(){
116 #ifndef ONLINE_JUDGE
117     freopen("4556.in" , "r" , stdin);
118     //freopen("4556.out" , "w" , stdout);
119 #endif
120     N = read();
121     M = read();
122     for(int i = 1 ; i < N ; ++i){
123         int a = read() , b = read();
124         addEd(a , b);
125         addEd(b , a);
126     }
127     dfs(1 , 0);
128     for(int i = 1 ; i <= M ; ++i){
129         int a = read() , b = read() , c = read() , t = LCA(a , b);
130         insert(root[a] , 1 , MAXN , c , 1);
131         insert(root[b] , 1 , MAXN , c , 1);
132         insert(root[t] , 1 , MAXN , c , -1);
133         insert(root[jump[t][0]] , 1 , MAXN , c , -1);
134     }
135     getAns(1);
136     for(int i = 1 ; i <= N ; ++i)
137         printf("%d\n" , ans[i]);
138     return 0;
139 }

Luogu4556 雨天的尾巴 树上差分、线段树合并

标签:style   16px   get   size   line   pac   pen   bsp   head   

原文地址:https://www.cnblogs.com/Itst/p/10069417.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!