CF191C 树链剖分

来源:互联网 发布:艾美仕怎么样 知乎 编辑:程序博客网 时间:2024/06/11 05:10


点击打开链接

给出K个路径, 统计经过每条边的次数。

边的标记 与 下面的u一致


const  int  maxn = 100008 ;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  c[maxn] ;int  lowbit(int x){     return x & (-x) ;}int  in(int i , int d){     for( ; i <= n ; i += lowbit(i)) c[i] += d ;}int  gsum(int i){     int t = 0 ;     for( ; i >= 1 ; i -= lowbit(i)) t += c[i] ;     return t  ;}struct  Line{      int  u ,  v , id ;}li[maxn]  ;void  change(int x , int y){      while(top[x] != top[y]){           if(dep[top[x]] < dep[top[y]]) std::swap(x , y) ;           in(tid[top[x]] , 1) ;           in(tid[x] + 1 , -1) ;           x = fa[top[x]] ;      }      if(x == y) return  ;      if(dep[x] > dep[y]) std::swap(x , y) ;      in(tid[x]+1 , 1) ;      in(tid[y]+1 , -1) ;}int   main(){      int i , j , u , v  , k  ;      while(scanf("%d" , &n) != EOF){           init() ;           for(i = 1 ; i < n ; i++){                scanf("%d%d" , &li[i].u , &li[i].v) ;                li[i].id = i ;                addedge(li[i].u , li[i].v) ;           }           dfs1(1 , 0 , 0) ;           dfs2(1 , 1) ;           for(i = 1 ; i < n ; i++){                if(tid[li[i].u] < tid[li[i].v])                    std::swap(li[i].u , li[i].v) ;           }           memset(c , 0 , sizeof(c)) ;           scanf("%d" , &k) ;           for(i = 1 ; i <= k ; i++){                scanf("%d%d" , &u , &v) ;                change(u , v) ;           }           for(i = 1 ; i < n ; i++)  printf("%d " , gsum(tid[li[i].u]))  ;           puts("") ;      }      return  0 ;}


0 0
原创粉丝点击