bzoj 5457 城市
Description
有n座城市,m个民族。这些城市之间由n-1条道路连接形成了以城市1为根的有根树。每个城市都是某一民族的聚居
地,Master知道第i个城市的民族是A_i,人数是B_i。为了维护稳定,Master需要知道某个区域内人数最多的民族
。他向你提出n个询问,其中第i个询问是:求以i为根的子树内,人数最多的民族有是哪个,这个民族有多少人。
如果子树内人数最多的民族有多个,输出其中编号最小的民族。
Input
共有2*n行。
第一行有两个整数n, m。
接下来n-1行,每行有两个整数u, v,表示一条连接u和v的道路。
接下来n行,第i行有两个整数A_i, B_i。
n<=400000,m<=n,1<=A_i<=m,0<=B_i<=1000。
Output
共有n行。
第i行两个整数x, y,分别表示以i为根的子树中人数最多的民族和它的人数。
Sample Input
8 6
1 2
1 3
2 4
4 5
3 6
5 7
1 8
2 8
2 5
1 1
3 1
6 7
5 6
1 10
4 6
1 2
1 3
2 4
4 5
3 6
5 7
1 8
2 8
2 5
1 1
3 1
6 7
5 6
1 10
4 6
Sample Output
2 13
1 10
5 6
1 10
1 10
5 6
1 10
4 6
1 10
5 6
1 10
1 10
5 6
1 10
4 6
思路: 从叶子开始往上不断的进行线段树合并。 用了一个pair,比较方便。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define R register int 4 #define rep(i,a,b) for(R i=a;i<=b;i++) 5 #define Rep(i,a,b) for(R i=a;i>=b;i--) 6 #define ms(i,a) memset(a,i,sizeof(a)) 7 #define gc() getchar() 8 #define mid (l+r>>1) 9 #define pii pair<int,int> 10 #define fi first 11 #define se second 12 template<class T>void read(T &x){ 13 x=0; char c=0; 14 while (!isdigit(c)) c=gc(); 15 while (isdigit(c)) x=x*10+(c^48),c=gc(); 16 } 17 int const N=400000+3; 18 struct Edge{ 19 int to,nt; 20 }E[N<<1]; 21 int H[N],cnt,n,m,a[N],b[N],rt[N],lc[N*30],rc[N*30],sum; 22 pii ans[N],mx[N*30]; 23 void add(int a,int b){ 24 E[cnt]=(Edge){b,H[a]}; H[a]=cnt++; 25 } 26 int merge(int x,int y,int l,int r){ 27 if(!x) return y; 28 if(!y) return x; 29 if(l==r) mx[x].fi+=mx[y].fi; 30 else { 31 lc[x]=merge(lc[x],lc[y],l,mid); 32 rc[x]=merge(rc[x],rc[y],mid+1,r); 33 mx[x]=max(mx[lc[x]],mx[rc[x]]); 34 } 35 return x; 36 } 37 void update(int &x,int l,int r,int a,int b){ 38 if(!x) x=++sum; 39 if(l==r){ 40 mx[x].fi+=b;mx[x].se=-a; 41 return ; 42 } 43 if(a<=mid) update(lc[x],l,mid,a,b); 44 else update(rc[x],mid+1,r,a,b); 45 mx[x]=max(mx[lc[x]],mx[rc[x]]); 46 } 47 void dfs(int x,int fa){ 48 for(R i=H[x];i!=-1;i=E[i].nt){ 49 int v=E[i].to; 50 if(v==fa) continue; 51 dfs(v,x); 52 rt[x]=merge(rt[x],rt[v],1,m); 53 } 54 update(rt[x],1,m,a[x],b[x]); 55 ans[x]=mx[rt[x]]; 56 } 57 int main(){ 58 read(n); read(m); 59 ms(-1,H); 60 rep(i,1,n-1){ 61 int x,y; 62 read(x); read(y); 63 add(x,y); add(y,x); 64 } 65 rep(i,1,n) read(a[i]),read(b[i]); 66 dfs(1,0); 67 rep(i,1,n) printf("%d %d\n",-ans[i].se,ans[i].fi); 68 return 0; 69 }