zoukankan      html  css  js  c++  java
  • SPOJ QTREE-Query on a tree-树链剖分-边权

    用每个点代表父节点到此点的边。建立一一映射后就可以用点权的方法处理了。

    注意的是路径两端节点的处理

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <vector>
      4 
      5 using namespace std;
      6 
      7 const int maxn = 1e5+5;
      8 int val[maxn],dep[maxn],siz[maxn],top[maxn],id[maxn],son[maxn],fa[maxn];
      9 int topw,M;
     10 
     11 vector<int> G[maxn];
     12 struct Edge{
     13     int x,y,val;
     14 }e[maxn];
     15 
     16 void dfs_1(int u,int f,int d)
     17 {
     18     fa[u] = f;
     19     son[u] = 0;
     20     siz[u] = 1;
     21     dep[u] = d;
     22 
     23     for(int i=0;i<G[u].size();i++) if(G[u][i] != f )
     24     {
     25         dfs_1(G[u][i],u,d+1);
     26         siz[u] += siz[G[u][i]];
     27         if(siz[son[u] ] < siz[G[u][i] ])
     28         {
     29             son[u] = G[u][i];
     30         }
     31     }
     32 }
     33 
     34 void dfs_2(int u,int tp)
     35 {
     36     top[u] = tp;
     37     id[u] = ++topw;
     38     if(son[u]) dfs_2(son[u],tp);
     39     for(int i=0;i<G[u].size();i++) if(G[u][i] != fa[u] && G[u][i] != son[u])
     40     {
     41         dfs_2(G[u][i],G[u][i]);
     42     }
     43 }
     44 
     45 int N,T;
     46 
     47 void debug()
     48 {
     49     for(int i=1;i<=N;i++)
     50     {
     51         printf("%d siz:%d son:%d dep:%d fa:%d ",i,siz[i],son[i],dep[i],fa[i]);
     52         printf("top:%d id:%d
    ",top[i],id[i]);
     53     }
     54 }
     55 
     56 /*-------------------------------------*/
     57 //segment Tree
     58 #define lson(x) (x<<1)
     59 #define rson(x) (x<<1|1)
     60 
     61 struct SegmentTree{
     62     int l,r,val;
     63 }sgtree[4*maxn];
     64 
     65 void pushup(int x)
     66 {
     67     sgtree[x].val = max(sgtree[lson(x)].val,sgtree[rson(x)].val);
     68 }
     69 
     70 void Build(int l,int r,int x)
     71 {
     72     sgtree[x].l = l;
     73     sgtree[x].r = r;
     74     if(l==r)
     75     {
     76         sgtree[x].val = val[l];
     77         return ;
     78     }
     79     int mid = (l+r)>>1;
     80     Build(l,mid,lson(x));
     81     Build(mid+1,r,rson(x));
     82     pushup(x);
     83 }
     84 
     85 void update(int x,int v,int add)
     86 {
     87     if(sgtree[x].l == sgtree[x].r)
     88     {
     89         sgtree[x].val = add;
     90         //printf("change:%d %d
    ",v,sgtree[x].l);
     91         return ;
     92     }
     93     int mid = (sgtree[x].l+sgtree[x].r)>>1;
     94     if(v <= mid) update(lson(x),v,add);
     95     else         update(rson(x),v,add);
     96     pushup(x);
     97 }
     98 
     99 int query(int x,int l,int r)
    100 {
    101     if(sgtree[x].l >= l && sgtree[x].r <= r)
    102     {
    103         return sgtree[x].val;
    104     }
    105     int mid = (sgtree[x].l+sgtree[x].r)>>1;
    106     int ans = 0;
    107     if(l <= mid) ans = max(ans,query(lson(x),l,r));
    108     if(r >  mid) ans = max(ans,query(rson(x),l,r));
    109     return ans;
    110 }
    111 
    112 int Find(int u,int v)
    113 {
    114     int ans = 0,fu = top[u],fv = top[v];
    115     while(fu != fv)
    116     {
    117         if(dep[fu] < dep[fv])
    118         {
    119             swap(fu,fv);swap(u,v);
    120         }
    121         ans = max(ans,query(1,id[fu],id[u]));
    122         u = fa[fu];
    123         fu = top[u];
    124     }
    125     if(u == v) return ans;
    126     if(dep[u]>dep[v]) swap(u,v);
    127     return max(ans,query(1,id[son[u] ],id[v]));
    128 }
    129 
    130 int main()
    131 {
    132     //freopen("input.in","r",stdin);
    133     scanf("%d",&T);
    134     while(T--)
    135     {
    136         scanf("%d",&N);
    137         for(int i=1,a,b,c;i<N;i++)
    138         {
    139             scanf("%d%d%d",&a,&b,&c);
    140             e[i].x = a;
    141             e[i].y = b;
    142             e[i].val = c;
    143             G[a].push_back(b);
    144             G[b].push_back(a);
    145         }
    146         topw = 0;
    147         dfs_1(1,0,1);
    148         dfs_2(1,1);
    149         //debug();
    150 
    151         for(int i=1;i<N;i++)
    152         {
    153             if(dep[e[i].x] < dep[e[i].y]) swap(e[i].x,e[i].y);
    154             val[id[e[i].x]] = e[i].val;
    155         }
    156 
    157         Build(1,topw,1);
    158         char op[100];
    159         while(scanf("%s",op) && op[0] != 'D')
    160         {
    161             int a,b;
    162             scanf("%d%d",&a,&b);
    163             if(op[0] == 'Q')
    164                 printf("%d
    ",Find(a,b));
    165             else if(op[0] == 'C')
    166                 update(1,id[e[a].x],b);
    167         }
    168 
    169         for(int i=1;i<=N;i++) G[i].clear();
    170     }
    171 }
  • 相关阅读:
    poj 3304线段与直线相交
    poj 1039 几何没思路
    zoj 1010 (线段相交判断+多边形求面积)
    poj 1654 Area (多边形求面积)
    poj 3348--Cows(凸包求面积)
    zoj 2107&&hdu 1007最近点对问题
    Codeforces Round #260 (Div. 2)AB
    MMORPG大型游戏设计与开发(part1 of net)
    MMORPG大型游戏设计与开发(规范)
    MMORPG大型游戏设计与开发(构架)
  • 原文地址:https://www.cnblogs.com/helica/p/5670400.html
Copyright © 2011-2022 走看看