zoukankan      html  css  js  c++  java
  • 树链剖分 模板

    关于树链剖分

    模板:

     1 const int MAXN = 20010;
     2 struct Edge
     3 {
     4     int to,next;
     5 } edge[MAXN*2];
     6 int head[MAXN],tot;
     7 
     8 int top[MAXN];//top[v]表示v所在的重链的顶端节点
     9 int fa[MAXN]; //父亲节点
    10 int deep[MAXN];//深度
    11 int num[MAXN];//num[v]表示以v为根的子树的节点数
    12 int p[MAXN];//p[v]表示v与其父亲节点的连边在线段树中的位置
    13 int fp[MAXN];//和p数组相反
    14 int son[MAXN];//重儿子
    15 int pos;
    16 
    17 int n;
    18 
    19 void init()
    20 {
    21     tot = 0;
    22     memset(head,-1,sizeof(head));
    23     pos = 1;//序号其实是从1开始?
    24     memset(son,-1,sizeof(son));
    25 }
    26 void addedge(int u,int v)
    27 {
    28     edge[tot].to = v;
    29     edge[tot].next = head[u];
    30     head[u] = tot++;
    31 }
    32 void dfs1(int u,int pre,int d) //第一遍dfs求出fa,deep,num,son
    33 {
    34     deep[u] = d;
    35     fa[u] = pre;
    36     num[u] = 1;
    37     for(int i = head[u]; i != -1; i = edge[i].next)
    38     {
    39         int v = edge[i].to;
    40         //因为路径是双向的,所以不能等于父及诶单
    41         if(v != pre)
    42         {
    43             //先递归地找到儿子节点的深度,父节点,子节点数目等信息
    44             dfs1(v,u,d+1);
    45             //更新u节点的儿子数目
    46             num[u] += num[v];
    47             if(son[u] == -1 || num[v] > num[son[u]])//求出重儿子
    48                 son[u] = v;
    49         }
    50     }
    51 }
    52 
    53 //因为对于轻儿子来说,top[u]=u,对于重儿子来说,如果son[v]!=-1,那么top[v]=top[son[v]]
    54 void getpos(int u,int sp) //第二遍dfs求出top和p
    55 {
    56     top[u] = sp;
    57     //先找重儿子
    58     if(son[u] != -1)
    59     {
    60         //把边的位置标记一下
    61         p[u] = pos++;
    62         //fp相当于是p的反函数?
    63         fp[p[u]] = u;
    64         //更新重儿子
    65         getpos(son[u],sp);
    66     }
    67     //如果到了叶子节点
    68     else
    69     {
    70         //不再向下dfs
    71         p[u] = pos++;
    72         fp[p[u]] = u;
    73         return;
    74     }
    75     //更新其他的节点
    76     for(int i = head[u] ; i != -1; i = edge[i].next)
    77     {
    78         int v = edge[i].to;
    79         if(v != son[u] && v != fa[u])
    80             getpos(v,v);
    81     }
    82 }
  • 相关阅读:
    【POJ 1958】 Strange Towers of Hanoi
    【HNOI 2003】 激光炸弹
    【POJ 3263】 Tallest Cow
    【POJ 2689】 Prime Distance
    【POJ 2777】 Count Color
    【POJ 1995】 Raising Modulo Numbers
    【POJ 1845】 Sumdiv
    6月16日省中集训题解
    【TJOI 2018】数学计算
    【POJ 1275】 Cashier Employment
  • 原文地址:https://www.cnblogs.com/wang-ya-wei/p/7440831.html
Copyright © 2011-2022 走看看