HDU5029 树链剖分

来源:互联网 发布:村招募淘宝com报名网站 编辑:程序博客网 时间:2024/06/14 16:07

2个经典的模型放在一块就成为一道难题。


const  int  maxn = 100018 ;int  n ;int  siz[maxn] , top[maxn] , son[maxn] ;int  dep[maxn] , tid[maxn] , fa[maxn] , rank[maxn]  ;int  head[maxn] , to[maxn*2] , next[maxn*2] , edge ;int  tim ;void  init(){      memset(head , -1 , sizeof(head)) ;      memset(son , -1 , sizeof(son))  ;      tim = edge = 0 ;}void  addedge(int u , int v){      to[edge] = v , next[edge] = head[u] , head[u] = edge++ ;      to[edge] = u , next[edge] = head[v] , head[v] = edge++ ;}void  dfs1(int u , int father , int d){      dep[u] = d ;      fa[u]  = father ;      siz[u] = 1 ;      for(int i = head[u] ; i != -1 ; i = next[i]){            int v = to[i] ;            if(v != father){                 dfs1(v , u , d+1) ;                 siz[u] += siz[v] ;                 if(son[u] == -1 || siz[v] > siz[son[u]]) son[u] = v ;            }      }}void  dfs2(int u , int tp){      top[u] = tp ;      tid[u] = ++tim ;      rank[tid[u]] = u ;      if(son[u] == -1) return  ;      dfs2(son[u] , tp) ;      for(int i = head[u] ; i != -1 ; i = next[i]){           int v = to[i] ;           if(v != son[u] && v != fa[u])  dfs2(v , v) ;      }}int   mcnt[maxn<<2] , mvalue[maxn<<2] ;void   up(int t){       if(mcnt[t<<1] >= mcnt[t<<1|1]){             mcnt[t] = mcnt[t<<1] ;             mvalue[t] = mvalue[t<<1] ;       }       else{             mcnt[t] = mcnt[t<<1|1] ;             mvalue[t] = mvalue[t<<1|1] ;       }       if(mcnt[t] == 0) mvalue[t] = 0 ;}void  make(int l , int r , int t){      if(l == r){           mvalue[t] = l ;           mcnt[t]   = 0 ;           return  ;      }      int  m = (l + r) >> 1 ;      make(l , m , t<<1) ;      make(m+1 , r , t<<1|1) ;      up(t) ;}void  update(int l , int r , int t , int x , int c){      if(l == r){            mcnt[t] += c ;            return  ;      }      int  m = (l + r) >> 1 ;      if(x <= m)  update(l , m , t<<1 , x , c) ;      if(x >  m)  update(m+1 , r , t<<1|1 , x , c) ;      up(t) ;}vector< pair<int , int> > line[maxn]  ;vector< pair<int , int> > ::iterator it  ;void  chage(int x , int y , int c){      while(top[x] != top[y]){           if(dep[top[x]] < dep[top[y]])  swap(x , y) ;           line[tid[top[x]]].push_back(make_pair(c , 1)) ;           line[tid[x] + 1].push_back(make_pair(c , -1)) ;           x = fa[top[x]] ;      }      if(tid[x] > tid[y]) swap(x , y) ;      line[tid[x]].push_back(make_pair(c , 1)) ;      line[tid[y]+1].push_back(make_pair(c , -1)) ;}int  ans[maxn] ;int  main(){     int i , m , u , v , c ;     while(scanf("%d%d" , &n , &m)){          if(n == 0 && m == 0) break ;          init() ;          for(i = 1 ; i < n ; i++){               scanf("%d%d" , &u , &v)  ;               addedge(u , v) ;          }          dfs1(1 , 0 , 0) ;          dfs2(1 , 1) ;          for(i = 0 ; i <= n+1 ; i++) line[i].clear() ;          int  gg  = 0 ;          while(m--){               scanf("%d%d%d" , &u ,&v ,&c) ;               chage(u , v , c) ;               gg = std::max(gg , c) ;          }          gg += 2 ;          make(1 , gg , 1) ;          for(i = 1 ; i <= n ; i++){               for(it = line[i].begin() ; it != line[i].end() ; it++)                    update(1 , gg , 1 , it->first ,it->second) ;               ans[rank[i]] = mvalue[1] ;          }          for(i = 1 ; i <= n ; i++) printf("%d\n" , ans[i]) ;     }     return  0  ;}


0 0
原创粉丝点击