[树链剖分][权值线段树]雨天的尾巴

Description

N个点,形成一个树状结构。有M次发放,每次选择两个点x,y
对于x到y的路径上(含x,y)每个点发一袋Z类型的物品。完成
所有发放后,每个点存放最多的是哪种物品。

Input

第一行数字N,M
接下来N-1行,每行两个数字a,b,表示a与b间有一条边
再接下来M行,每行三个数字x,y,z.如题

Output


输出有N行
每i行的数字表示第i个点存放最多的物品是哪一种,如果有
多种物品的数量一样,输出编号最小的。如果某个点没有物品
则输出0

1<=N,M<=100000
1<=a,b,x,y<=N
1<=z<=10^9

题解

 思想很妙啊!

 

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<vector>
 4 using namespace std;
 5 const int N=100000+5;
 6 int n,m;
 7 int num,last[N],nxt[2*N],ver[2*N];
 8 inline void add(int x,int y) {nxt[++num]=last[x]; last[x]=num; ver[num]=y;}
 9 
10 int fa[N],deep[N],son[N],siz[N];
11 void build(int x)
12  {siz[x]=1;
13   for(int i=last[x];i;i=nxt[i])
14    {int y=ver[i];
15     if(y==fa[x]) continue;
16     
17     fa[y]=x; deep[y]=deep[x]+1;
18     
19     build(y);     siz[x]+=siz[y];
20     if(siz[y]>siz[son[x]]) son[x]=y;
21    }    
22  }
23 int id,ord[N],a[N],top[N]; 
24 void dfs(int x) 
25  {ord[x]=++id; a[id]=x;
26   
27   if(son[fa[x]]==x) top[x]=top[fa[x]];
28   else              top[x]=x;
29   
30   if(son[x]) dfs(son[x]);
31   for(int i=last[x];i;i=nxt[i])
32    if(ver[i]!=fa[x] && ver[i]!=son[x]) 
33      dfs(ver[i]);
34  }
35 
36 vector<int> q[N];
37 struct point{int l,r,maxx,pos;}t[4*N];
38 void build(int i,int l,int r)
39  {t[i].l=l; t[i].r=r; 
40   if(l==r) {t[i].pos=l; return;}
41   int mid=t[i].l+t[i].r>>1;
42   build(2*i,l,mid); build(2*i+1,mid+1,r);
43  }
44 void add(int i,int pos,int x)
45  {if(t[i].l==t[i].r) {t[i].maxx+=x; return;}
46   int mid=t[i].l+t[i].r>>1;
47   if(pos<=mid) add(2*i,pos,x);
48   else         add(2*i+1,pos,x);
49   
50   if(t[2*i].maxx>=t[2*i+1].maxx) t[i].maxx=t[2*i].maxx,t[i].pos=t[2*i].pos;
51   else                           t[i].maxx=t[2*i+1].maxx,t[i].pos=t[2*i+1].pos;
52  }  
53 inline void query(int x,int y,int z)
54  {
55   while(top[x]!=top[y])    
56    {if(deep[top[x]]<deep[top[y]]) swap(x,y);
57    
58     // top[x] x
59     q[ord[top[x]]].push_back(z); q[ord[x]+1].push_back(-z);
60     x=fa[top[x]];
61    }
62   if(deep[x]<deep[y]) swap(x,y);
63   q[ord[y]].push_back(z); q[ord[x]+1].push_back(-z); 
64  }
65 int ans[N]; 
66 int main()
67  {        
68  scanf("%d%d",&n,&m); int x,y,z;    
69  for(int i=1;i<n;i++) {scanf("%d%d",&x,&y); add(x,y); add(y,x); }    
70      
71  deep[1]=1; build(1); dfs(1);    build(1,1,100000+5);
72      
73  while(m--)    
74   {scanf("%d%d%d",&x,&y,&z);
75    query(x,y,z);
76   }    
77  
78  for(int i=1;i<=n;i++)    
79   {for(int j=0;j<q[i].size();j++)
80      if(q[i][j]>0) add(1,q[i][j],1);
81      else          add(1,-q[i][j],-1);
82    if(t[1].maxx) ans[a[i]]=t[1].pos;
83    else          ans[a[i]]=0;    
84   }        
85  for(int i=1;i<=n;i++) printf("%d\n",ans[i]); 
86 return 0;
87  }

 

 

 

 

posted @ 2019-07-27 21:13  YuXiaoze  阅读(201)  评论(0编辑  收藏  举报