SPOJ 375. Query on a tree (树链剖分)

Query on a tree

Time Limit: 5000ms
Memory Limit: 262144KB
 
This problem will be judged on SPOJ. Original ID: QTREE
64-bit integer IO format: %lld      Java class name: Main
Font Size:  +  -
Type:   None   Graph Theory       2-SAT       Articulation/Bridge/Biconnected Component       Cycles/Topological Sorting/Strongly Connected Component       Shortest Path           Bellman Ford           Dijkstra/Floyd Warshall       Euler Trail/Circuit       Heavy-Light Decomposition       Minimum Spanning Tree       Stable Marriage Problem       Trees       Directed Minimum Spanning Tree       Flow/Matching           Graph Matching               Bipartite Matching               Hopcroft–Karp Bipartite Matching               Weighted Bipartite Matching/Hungarian Algorithm           Flow               Max Flow/Min Cut               Min Cost Max Flow   DFS-like       Backtracking with Pruning/Branch and Bound       Basic Recursion       IDA* Search       Parsing/Grammar       Breadth First Search/Depth First Search       Advanced Search Techniques           Binary Search/Bisection           Ternary Search   Geometry       Basic Geometry       Computational Geometry       Convex Hull       Pick's Theorem   Game Theory       Green Hackenbush/Colon Principle/Fusion Principle       Nim       Sprague-Grundy Number   Matrix       Gaussian Elimination       Matrix Exponentiation   Data Structures       Basic Data Structures       Binary Indexed Tree       Binary Search Tree       Hashing       Orthogonal Range Search       Range Minimum Query/Lowest Common Ancestor       Segment Tree/Interval Tree       Trie Tree       Sorting       Disjoint Set   String       Aho Corasick       Knuth-Morris-Pratt       Suffix Array/Suffix Tree   Math       Basic Math       Big Integer Arithmetic       Number Theory           Chinese Remainder Theorem           Extended Euclid           Inclusion/Exclusion           Modular Arithmetic       Combinatorics           Group Theory/Burnside's lemma           Counting       Probability/Expected Value   Others       Tricky       Hardest       Unusual       Brute Force       Implementation       Constructive Algorithms       Two Pointer       Bitmask       Beginner       Discrete Logarithm/Shank's Baby-step Giant-step Algorithm       Greedy       Divide and Conquer   Dynamic Programming                      Tag it!

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\n",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 }

 

转载于:https://www.cnblogs.com/tom987690183/p/4067043.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值