[HDU5029]Relief grain(树链剖分+线段树)

两种显然的做法:

1.树上差分+线段树合并。$O(n\log n)$

2.树链剖分转为序列上差分+线段树。$O(n\log^2 n)$

后一种的代码:

 1 #include<cstdio>
 2 #include<vector>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 #define ls (x<<1)
 7 #define rs (ls|1)
 8 #define lson ls,L,mid
 9 #define rson rs,mid+1,R
10 #define mem(a) memset(a,0,sizeof(a))
11 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
12 #define For(i,x) for (int i=h[x],k; i; i=nxt[i])
13 typedef long long ll;
14 using namespace std;
15 
16 const int N=100010;
17 int n,m,u,v,w,tim,cnt,id[N<<2],s[N<<2],to[N<<1],nxt[N<<1];
18 int son[N],top[N],pos[N],d[N],sz[N],ans[N],fa[N],h[N];
19 vector<int>V[N];
20 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
21 void init(){
22     cnt=0; tim=0;
23     rep(i,1,n) h[i]=son[i]=0,V[i].clear();
24 }
25 
26 void dfs1(int x){
27     sz[x]=1; d[x]=d[fa[x]]+1;
28     For(i,x) if ((k=to[i])!=fa[x]){
29         fa[k]=x; dfs1(k); sz[x]+=sz[k];
30         if (sz[k]>sz[son[x]]) son[x]=k;
31     }
32 }
33 
34 void dfs2(int x,int z){
35     pos[x]=++tim; top[x]=z;
36     if (son[x]) dfs2(son[x],z);
37     For(i,x) if ((k=to[i])!=fa[x] && k!=son[x]) dfs2(k,k);
38 }
39 
40 void work(int l,int r,int c){ V[l].push_back(c),V[r+1].push_back(-c); }
41 
42 void solve(int u,int v,int c){
43     for (; top[u]!=top[v]; u=fa[top[u]]){
44         if (d[top[u]]<d[top[v]]) swap(u,v);
45         work(pos[top[u]],pos[u],c);
46     }
47     if (d[u]>d[v]) swap(u,v);
48     work(pos[u],pos[v],c);
49 }
50 
51 void upd(int x){
52     int k=s[ls]<s[rs] ? rs : ls;
53     s[x]=s[k]; id[x]=id[k];
54 }
55 
56 void build(int x,int L,int R){
57     if (L==R){ s[x]=0; id[x]=L; return; }
58     int mid=(L+R)>>1;
59     build(lson); build(rson); upd(x);
60 }
61 
62 void ins(int x,int L,int R,int pos,int k){
63     if (L==R){ s[x]+=k; return; }
64     int mid=(L+R)>>1;
65     if (pos<=mid) ins(lson,pos,k); else ins(rson,pos,k);
66     upd(x);
67 }
68 
69 int main(){
70     freopen("hdu5029.in","r",stdin);
71     freopen("hdu5029.out","w",stdout);
72     while (scanf("%d%d",&n,&m)==2 && n+m){
73         init(); int mx=0;
74         rep(i,2,n) scanf("%d%d",&u,&v),add(u,v),add(v,u);
75         fa[1]=0; dfs1(1); dfs2(1,1);
76         rep(i,1,m) scanf("%d%d%d",&u,&v,&w),solve(u,v,w),mx=max(mx,w);
77         build(1,0,mx);
78         rep(i,1,n){
79             rep(j,0,(int)V[i].size()-1)
80                 if (V[i][j]>0) ins(1,0,mx,V[i][j],1); else ins(1,0,mx,-V[i][j],-1);
81             ans[i]=id[1];
82         }
83         rep(i,1,n) printf("%d\n",ans[pos[i]]);
84     }
85     return 0;
86 }

 

posted @ 2018-10-30 23:31  HocRiser  阅读(213)  评论(0编辑  收藏  举报