HDU5029 树链剖分

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 > line[maxn]  ;
vector< pair > ::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  ;
}


你可能感兴趣的:(C++足迹)