[树链剖分][权值线段树]雨天的尾巴
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 }