zoukankan      html  css  js  c++  java
  • SPOJ375.QTREE树链剖分

    题意:一个树,a b c 代表a--b边的权值为c。CHANGE x y  把输入的第x条边的权值改为y,QUERY x y 查询x--y路径上边的权值的最大值。

    第一次写树链剖分,其实树链剖分只能说是一种思想。树链剖分  就是 先选择从根节点到叶子节点的最长的路径的权值对应到线段树上,然后从一个子树的根节点到叶子的最长路径的权值对应到线段树上这样直到把所有的点都处理了,然后就是线段树区间查询最值了。

    具体可以看这个博客。http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <iostream>
      4 #include <cstring>
      5 #include <algorithm>
      6 using namespace std;
      7 typedef unsigned long long ull;
      8 typedef long long ll;
      9 const int inf = 0x3f3f3f3f;
     10 const double eps = 1e-8;
     11 const int maxn = 1e4+10;
     12 int top[maxn],fa[maxn],son[maxn],dep[maxn],siz[maxn],seg_tree[maxn<<2],head[maxn],pos[maxn];
     13 int edge,tot;
     14 struct
     15 {
     16     int to,next;
     17 }e[maxn<<1];
     18 void add(int x,int y)
     19 {
     20     e[edge].to = y;
     21     e[edge].next = head[x];
     22     head[x] = edge++;
     23 }
     24 
     25 void dfs(int r)
     26 {
     27     siz[r] = 1;
     28     son[r] = 0;
     29     for (int i = head[r]; i > 0; i = e[i].next)
     30         if (fa[r] != e[i].to)
     31         {
     32             dep[e[i].to] = dep[r] + 1;
     33             fa[e[i].to] = r;
     34             dfs(e[i].to);
     35             if (siz[e[i].to] > siz[son[r]])
     36                 son[r] = e[i].to;
     37             siz[r] += siz[e[i].to];
     38         }
     39 }
     40 
     41 void build(int r,int f)
     42 {
     43     pos[r] = tot++;
     44     top[r] = f;
     45     if (son[r] > 0)
     46         build(son[r],top[r]);
     47     for (int i = head[r]; i > 0; i = e[i].next)
     48     {
     49         if (fa[r] != e[i].to && son[r] != e[i].to)
     50             build(e[i].to,e[i].to);
     51     }
     52 }
     53 
     54 void update(int l,int r,int o,int x,int v)
     55 {
     56     if (l == r)
     57     {
     58         seg_tree[o] = v;
     59         return;
     60     }
     61     int mid = (l + r) >> 1;
     62     if (x <= mid)
     63         update(l,mid,o<<1,x,v);
     64     if (x > mid)
     65         update(mid+1,r,o<<1|1,x,v);
     66     seg_tree[o] = max(seg_tree[o<<1],seg_tree[o<<1|1]);
     67 }
     68 
     69 int query(int l,int r,int o,int ua,int ub)
     70 {
     71     if (ua <= l && ub >= r)
     72         return seg_tree[o];
     73     int mid = (l + r) >> 1;
     74     int t1,t2;
     75     t1 = t2 = 0;
     76     if (ua <= mid)
     77         t1 = query(l,mid,o<<1,ua,ub);
     78     if (ub > mid)
     79         t2 = query(mid+1,r,o<<1|1,ua,ub);
     80     return max(t1,t2);
     81 }
     82 
     83 int get_max(int ua,int ub)
     84 {
     85     int f1 = top[ua];
     86     int f2 = top[ub];
     87     int tmp = 0;
     88     while (f1 != f2)
     89     {
     90         if (dep[f1] < dep[f2])
     91             swap(f1,f2),swap(ua,ub);
     92         tmp = max(tmp,query(1,tot,1,pos[f1],pos[ua]));
     93         ua = fa[f1],f1 = top[ua];
     94     }
     95     if (ua == ub)
     96         return tmp;
     97     if (dep[ua] > dep[ub])
     98         swap(ua,ub);
     99     tmp = max(tmp,query(1,tot,1,pos[son[ua]],pos[ub]));
    100     return tmp;
    101 }
    102 
    103 int d[maxn][3];
    104 void init()
    105 {
    106     int n;
    107     scanf ("%d",&n);
    108     memset(dep,0,sizeof(dep));
    109     memset(son,0,sizeof(son));
    110     memset(head,0,sizeof(head));
    111     memset(fa,0,sizeof(fa));
    112     memset(top,0,sizeof(top));
    113     int root = (n+1)>>1;
    114     fa[root] = dep[root] =0;
    115     tot = edge = 1;
    116     int a,b,c;
    117     for (int i = 1; i < n; i++)
    118     {
    119         scanf ("%d%d%d",&a,&b,&c);
    120         add(a,b),add(b,a);
    121         d[i][0] = a,d[i][1] = b,d[i][2] = c;
    122     }
    123     dfs(root);
    124     build(root,root);
    125     tot--;
    126     for (int i = 1; i < n; i++)
    127     {
    128         if (dep[d[i][0]] < dep[d[i][1]])
    129             swap(d[i][1],d[i][0]);
    130         update(1,tot,1,pos[d[i][0]],d[i][2]);
    131     }
    132 
    133 }
    134 int main(void)
    135 {
    136     #ifndef ONLINE_JUDGE
    137         freopen("in.txt","r",stdin);
    138     #endif // ONLINE_JUDGE
    139     int t;
    140     scanf ("%d",&t);
    141     while (t--)
    142     {
    143          init();
    144          char op[10];
    145          while (scanf ("%s",op),op[0] != 'D')
    146          {
    147              int x,y;
    148              scanf ("%d%d",&x,&y);
    149              if (op[0] == 'C')
    150                 update(1,tot,1,pos[d[x][0]],y);
    151             if (op[0] == 'Q')
    152                 printf("%d
    ",get_max(x,y));
    153          }
    154     }
    155     return 0;
    156 }
  • 相关阅读:
    view 与layer
    xcode中create groups 和 create folder reference 的区别
    iOS 9 学习系列:UIStack View (转载)
    使用JQuery插件,排序Gridview的某个字段
    Fixed GridView Header
    在TextBox里面仅仅允许数字,按Enter键进入下一个TextBox
    实现AJAX局部刷新以及PageMethod方法的使用
    用户控件
    JSON的使用
    ASP.NET页面生命周期
  • 原文地址:https://www.cnblogs.com/oneshot/p/4010293.html
Copyright © 2011-2022 走看看