SPOJ Query on a tree (树链剖分)
2015-09-17 00:34
796 查看
Query on a tree
Time Limit: 5000msMemory Limit: 262144KB
This problem will be judged on SPOJ. Original ID: QTREE
64-bit integer IO format: %lld Java class name: Main
Prev Submit Status Statistics Discuss Next
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 a, b 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
Tags ( Click to see )
Prev Submit Status Statistics Discuss Next代码:
#include <bits/stdc++.h>
#define lc(o) (o<<1)
#define rc(o) (o<<1|1)
using namespace std;
const int maxn = 1e4 + 10;
struct Edge{
int from,to,dist;
Edge(int u,int v,int w):from(u),to(v),dist(w){}
};
vector<int> g[maxn];
vector<Edge> edges;
void AddEdge(int u,int v,int w)
{
int m = edges.size();
g[u].push_back(m);
g[v].push_back(m);
edges.push_back(Edge(u,v,w));
}
int siz[maxn],son[maxn],fa[maxn],dep[maxn];
void pre(int u,int p)
{
dep[u] = dep[p] + 1;
siz[u] = 1;
fa[u] = p;
son[u] = 0;
for(vector<int>::iterator it = g[u].begin(); it != g[u].end(); ++it) {
Edge & e = edges[*it];
int v = e.to;
if(v == u) v = e.from;
if(v==p)continue;
pre(v,u);
siz[u] += siz[v];
if(siz[son[u]] < siz[v]) son[u] = v;
}
}
int root[maxn],pos[maxn],seg[maxn<<2],tot;
void built(int u,int t)
{
root[u] = t;
pos[u] = ++tot;
if(siz[u] == 1) return;
built(son[u],t);
for(vector<int>::iterator it = g[u].begin(); it != g[u].end(); ++it) {
Edge & e = edges[*it];
int v = e.to;
if(v == u) v = e.from;
if(v==fa[u]||v==son[u])continue;
built(v,v);
}
}
int ql,qr,val;
void Modify(int o,int L,int R)
{
if(L==R) {
seg[o] = val;
return;
}
int M = (L+R)>>1;
if(ql<=M) Modify(lc(o),L,M);
else Modify(rc(o),M+1,R);
seg[o] = max(seg[lc(o)],seg[rc(o)]);
}
int Query(int o,int L,int R)
{
if(ql<=L&&qr>=R) return seg[o];
int M = (L+R)>>1;
int ans = 0;
if(ql <= M) ans = Query(lc(o),L,M);
if(qr > M) ans = max(ans,Query(rc(o),M+1,R));
return ans;
}
int ask(int u,int v)
{
int ans = 0;
while(root[u] != root[v]) {
if(dep[root[u]] < dep[root[v]]) swap(u,v);
ql = pos[root[u]];
qr = pos[u];
if(ql <= qr) ans = max(ans,Query(1,1,tot));
u = fa[root[u]];
}
if(u==v)return ans;
ql = pos[u];
qr = pos[v];
if(ql > qr) swap(ql,qr);
ans = max(ans,Query(1,1,tot));
return ans;
}
int main()
{
int T;scanf("%d",&T);
siz[0] = 0;
while(T--) {
int n;scanf("%d",&n);
edges.clear();
edges.push_back(Edge(0,0,0));
for(int i = 1; i <= n; ++i) g[i].clear();
for(int i = 1; i < n; ++i) {
int u,v,w;scanf("%d%d%d",&u,&v,&w);
AddEdge(u,v,w);
}
pre(1,0);
tot = 0;
built(1,1);
memset(seg,0,sizeof(*seg)*(4*n));
for(int i = 1; i < n; ++i) {
Edge & e = edges[i-1];
if(dep[e.from] > dep[e.to]) swap(e.from,e.to);
val = e.dist;
ql = e.to;
Modify(1,1,tot);
}
char op[10];
int u,v;
while(scanf("%s",op) == 1)
{
if(op[0] == 'D')break;
scanf("%d%d",&u,&v);
if(op[0] == 'Q')
printf("%d\n",ask(u,v));
else {
ql = pos[edges[u-1].to];
val = v;
Modify(1,1,tot);
}
}
}
return 0;
}
相关文章推荐
- hybz1036 树的统计Count
- poj3237 Tree
- hybz2243 染色
- 【bzoj1036】【树链剖分】【ZJOI2008】树的统计Count
- FZU 2082 树链剖分 区间最大和
- spoj 1825 Free tour II(树的点分治)
- HDU 5274(树链剖分)
- SPOJ 375 QTREE系列-Query on a tree (树链剖分)
- HDU 3966 Aragorn's Story (树链剖分)
- POJ 2763 Housewife Wind (树链剖分)
- POJ 3237 Tree (树链剖分)
- FZU 2082 过路费 (树链剖分)
- BZOJ 1036 [ZJOI2008] 树的统计Count (树链剖分)
- BZOJ 2243 [SDOI2011] 染色 (树链剖分)
- LightOJ 1348 Aladdin and the Return Journey (树链剖分)
- POJ 1741 Tree (树上点分治)(楼教主男人八题之一)
- hdu 3966 Aragorn's Story (树链剖分)
- 树链剖分学习
- SPOJ375 QTREE 树链剖分入门
- Codeforces 375D 数据结构(好题中的好题, 4解)