zoukankan      html  css  js  c++  java
  • SPOJ 375. Query on a tree (树链剖分)

    Query on a tree

    5000ms
    262144KB
     
    This problem will be judged on SPOJ. Original ID: QTREE
    64-bit integer IO format: %lld      Java class name: Main
    Font Size:  
    Type:  

    You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1.

    We will ask you to perfrom some instructions of the following form:

    • CHANGE i ti : change the cost of the i-th edge to ti
      or
    • QUERY a b : ask for the maximum edge cost on the path from node a to node b

    Input

    The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.

    For each test case:

    • In the first line there is an integer N (N <= 10000),
    • In the next N-1 lines, the i-th line describes the i-th edge: a line with three integers a b c denotes an edge between ab of cost c (c <= 1000000),
    • The next lines contain instructions "CHANGE i ti" or "QUERY a b",
    • The end of each test case is signified by the string "DONE".

    There is one blank line between successive tests.

    Output

    For each "QUERY" operation, write one integer representing its result.

    Example

    Input:
    1
    
    3
    1 2 1
    2 3 2
    QUERY 1 2
    CHANGE 1 3
    QUERY 1 2
    DONE
    
    Output:
    1
    3

      1 #include<iostream>
      2 #include<stdio.h>
      3 #include<cstdlib>
      4 #include<cstring>
      5 using namespace std;
      6 const int maxn = 1e4+13;
      7 
      8 struct node
      9 {
     10     int l,r,Max;
     11 }f[maxn*4];
     12 
     13 struct Edge
     14 {
     15     int to,next;
     16 }edge[maxn*2];
     17 
     18 int e[maxn][3];
     19 int p[maxn];
     20 int top[maxn];
     21 int siz[maxn];
     22 int son[maxn];
     23 int deep[maxn];
     24 int father[maxn];
     25 int head[maxn];
     26 int num[maxn];
     27 int cont,pos;
     28 
     29 void init()
     30 {
     31     cont = 0;
     32     pos = 0;
     33     memset(head,-1,sizeof(head));
     34     memset(son,-1,sizeof(son));
     35 }
     36 void add(int n1,int n2)
     37 {
     38     edge[cont].to=n2;// 指向谁
     39     edge[cont].next=head[n1];
     40     head[n1]=cont;
     41     cont++;
     42 }
     43 
     44 void dfs1(int u,int pre,int d)/**fa deep,num,son**/
     45 {
     46     deep[u]=d;
     47     father[u]=pre;
     48     num[u]=1;
     49     for(int i=head[u];i!=-1;i=edge[i].next)
     50     {
     51         int v = edge[i].to;
     52         if(v!=pre)
     53         {
     54             dfs1(v,u,d+1);
     55             num[u]=num[u]+num[v];
     56             if(son[u]==-1 || num[v]>num[son[u]])
     57             son[u]=v;
     58         }
     59     }
     60 }
     61 
     62 void getops(int u,int sp)
     63 {
     64     top[u]=sp;
     65     if(son[u]!=-1)
     66     {
     67         p[u]=++pos;
     68         getops(son[u],sp);
     69     }
     70     else
     71     {
     72         p[u]=++pos;
     73         return;
     74     }
     75     for(int i=head[u];i!=-1;i=edge[i].next)
     76     {
     77         int v = edge[i].to;
     78         if(v!=son[u] && v!=father[u])
     79         getops(v,v);
     80     }
     81 }
     82 void build(int l,int r,int n)
     83 {
     84     f[n].l=l;
     85     f[n].r=r;
     86     f[n].Max=0;
     87     if(l==r)return;
     88     int mid=(l+r)/2;
     89     build(l,mid,n*2);
     90     build(mid+1,r,n*2+1);
     91 }
     92 int query(int l,int r,int n)
     93 {
     94     int mid=(f[n].l+f[n].r)/2;
     95     int ans1,ans2;
     96     if(f[n].l==l && f[n].r==r) return f[n].Max;
     97     if(mid>=r) return query(l,r,n*2);
     98     else if(mid<l) return query(l,r,n*2+1);
     99     else
    100     {
    101         ans1=query(l,mid,n*2);
    102         ans2=query(mid+1,r,n*2+1);
    103         if(ans1<ans2) ans1=ans2;
    104     }
    105     return ans1;
    106 }
    107 void update(int x,int num1,int n)
    108 {
    109     int mid=(f[n].l+f[n].r)/2;
    110     if(f[n].l == x && f[n].r == x)
    111     {
    112         f[n].Max=num1;
    113         return;
    114     }
    115     if(mid>=x) update(x,num1,n*2);
    116     else update(x,num1,n*2+1);
    117     f[n].Max = f[n*2].Max>f[n*2+1].Max? f[n*2].Max:f[n*2+1].Max;
    118 }
    119 int find(int u,int v)
    120 {
    121     int f1 = top[u],f2 = top[v];
    122     int MAX=0;
    123     while(f1!=f2)
    124     {
    125        if(deep[f1]<deep[f2])
    126        {
    127            swap(f1,f2);
    128            swap(u,v);
    129        }
    130        MAX=max(MAX,query(p[f1],p[u],1));
    131        u=father[f1];
    132        f1=top[u];
    133     }
    134     if(u==v)return MAX;
    135     if(deep[u]>deep[v])swap(u,v);
    136     return max(MAX,query(p[son[u]],p[v],1));
    137 }
    138 int main()
    139 {
    140     int T,n,l,r,x,num1;
    141     char a[12];
    142     scanf("%d",&T);
    143     while(T--)
    144     {
    145         scanf("%d",&n);
    146         init();
    147         for(int i=1;i<n;i++)
    148         {
    149             scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]);
    150             add(e[i][0],e[i][1]);
    151             add(e[i][1],e[i][0]);
    152         }
    153         dfs1(1,0,0);
    154         getops(1,1);
    155         build(1,pos,1);
    156         for(int i=1;i<n;i++)
    157         {
    158             if(deep[e[i][0]]>deep[e[i][1]]) swap(e[i][0],e[i][1]);
    159             update(p[e[i][1]],e[i][2],1);
    160         }
    161         while(scanf("%s",a)>0)
    162         {
    163             if(a[0]=='D')break;
    164             if(a[0]=='Q')
    165             {
    166                 scanf("%d%d",&l,&r);
    167                 printf("%d
    ",find(l,r));
    168             }
    169             else if(a[0]=='C')
    170             {
    171                 scanf("%d%d",&x,&num1);
    172                 update(p[e[x][1]],num1,1);
    173             }
    174         }
    175     }
    176     return 0;
    177 }
  • 相关阅读:
    Oracle的hash分区
    Oracle的list分区
    range联合分区
    Oracle分区表range单分区
    彻底解决Oracle unable to create INITIAL extent for segment in tablespace xx
    Oracle表空间管理,数据迁移,
    plsqldevelop安装教程
    count(*)与count列谁快谁慢
    阿里云服务器Centos6.9安装oracle11g单实例数据库
    字符转换二进制码
  • 原文地址:https://www.cnblogs.com/tom987690183/p/4067043.html
Copyright © 2011-2022 走看看