Query on a tree

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
第一次接触树链剖分,貌似是用来处理对树的边权的多次询问,然后对边权进行编号,转化为节点之间的询问。具体关于树链剖分的解析见 http://blog.csdn.net/acdreamers/article/details/10591443
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <time.h>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
#define lson(x) ((x<<1))
#define rson(x) ((x<<1)+1)
using namespace std;
typedef long long ll;
const int N=1e5+;
const int M=N*N+;
int dep[N],siz[N],fa[N],id[N],son[N],val[N],top[N]; //top 最近的重链父节点
int num;
vector<int> v[N];
struct tree {
int x,y,val;
void read() {
scanf("%d%d%d",&x,&y,&val);
}
};
tree e[N];
void dfs1(int u, int f, int d) {
dep[u] = d;
siz[u] = ;
son[u] = ;
fa[u] = f;
for (int i = ; i < v[u].size(); i++) {
int ff = v[u][i];
if (ff == f) continue;
dfs1(ff, u, d + );
siz[u] += siz[ff];
if (siz[son[u]] < siz[ff])
son[u] = ff;
}
}
void dfs2(int u, int tp) {
top[u] = tp;
id[u] = ++num;
if (son[u]) dfs2(son[u], tp);
for (int i = ; i < v[u].size(); i++) {
int ff = v[u][i];
if (ff == fa[u] || ff == son[u]) continue;
dfs2(ff, ff);
}
} struct Tree {
int l,r,val;
};
Tree tree[*N];
void pushup(int x) {
tree[x].val = max(tree[lson(x)].val, tree[rson(x)].val);
} void build(int l,int r,int v) {
tree[v].l=l;
tree[v].r=r;
if(l==r) {
tree[v].val = val[l];
return ;
}
int mid=(l+r)>>;
build(l,mid,v*);
build(mid+,r,v*+);
pushup(v);
}
void update(int o,int v,int val) { //log(n)
if(tree[o].l==tree[o].r) {
tree[o].val = val;
return ;
}
int mid = (tree[o].l+tree[o].r)/;
if(v<=mid)
update(o*,v,val);
else
update(o*+,v,val);
pushup(o);
}
int query(int x,int l, int r) {
if (tree[x].l >= l && tree[x].r <= r) {
return tree[x].val;
}
int mid = (tree[x].l + tree[x].r) / ;
int ans = ;
if (l <= mid) ans = max(ans, query(lson(x),l,r));
if (r > mid) ans = max(ans, query(rson(x),l,r));
return ans;
} int Yougth(int u, int v) {
int tp1 = top[u], tp2 = top[v];
int ans = ;
while (tp1 != tp2) {
if (dep[tp1] < dep[tp2]) {
swap(tp1, tp2);
swap(u, v);
}
ans = max(query(,id[tp1], id[u]), ans);
u = fa[tp1];
tp1 = top[u];
}
if (u == v) return ans;
if (dep[u] > dep[v]) swap(u, v);
ans = max(query(,id[son[u]], id[v]), ans);
return ans;
}
void Clear(int n) {
for(int i=; i<=n; i++)
v[i].clear();
}
int main() {
int T;
scanf("%d",&T);
while(T--) {
int n;
scanf("%d",&n);
for(int i=; i<n; i++) {
e[i].read();
v[e[i].x].push_back(e[i].y);
v[e[i].y].push_back(e[i].x);
}
num = ;
dfs1(,,);
dfs2(,);
for (int i = ; i < n; i++) {
if (dep[e[i].x] < dep[e[i].y]) swap(e[i].x, e[i].y);
val[id[e[i].x]] = e[i].val;
}
build(,num,);
char s[];
while(~scanf("%s",&s) && s[]!='D') {
int x,y;
scanf("%d%d",&x,&y);
if(s[]=='Q')
printf("%d\n",Yougth(x,y));
if (s[] == 'C')
update(,id[e[x].x],y);
}
Clear(n);
}
return ;
}

spoj 375 Query on a tree (树链剖分)的更多相关文章

  1. SPOJ 375 Query on a tree 树链剖分模板

    第一次写树剖~ #include<iostream> #include<cstring> #include<cstdio> #define L(u) u<&l ...

  2. SPOJ QTREE Query on a tree 树链剖分+线段树

    题目链接:http://www.spoj.com/problems/QTREE/en/ QTREE - Query on a tree #tree You are given a tree (an a ...

  3. spoj QTREE - Query on a tree(树链剖分+线段树单点更新,区间查询)

    传送门:Problem QTREE https://www.cnblogs.com/violet-acmer/p/9711441.html 题解: 树链剖分的模板题,看代码比看文字解析理解来的快~~~ ...

  4. SPOJ QTREE Query on a tree ——树链剖分 线段树

    [题目分析] 垃圾vjudge又挂了. 树链剖分裸题. 垃圾spoj,交了好几次,基本没改动却过了. [代码](自带常数,是别人的2倍左右) #include <cstdio> #incl ...

  5. SPOJ QTREE Query on a tree --树链剖分

    题意:给一棵树,每次更新某条边或者查询u->v路径上的边权最大值. 解法:做过上一题,这题就没太大问题了,以终点的标号作为边的标号,因为dfs只能给点分配位置,而一棵树每条树边的终点只有一个. ...

  6. spoj 375 QTREE - Query on a tree 树链剖分

    题目链接 给一棵树, 每条边有权值, 两种操作, 一种是将一条边的权值改变, 一种是询问u到v路径上最大的边的权值. 树链剖分模板. #include <iostream> #includ ...

  7. SPOJ Query on a tree 树链剖分 水题

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

  8. Query on a tree——树链剖分整理

    树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...

  9. Bzoj 2588 Spoj 10628. Count on a tree(树链剖分LCA+主席树)

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MB Description 给定一棵N个节点的树,每个点 ...

随机推荐

  1. SDK支付流程

    1.普通支付流程 2.代理流程 易接.U8SDK

  2. Python 装饰器初探

    Python 装饰器初探 在谈及Python的时候,装饰器一直就是道绕不过去的坎.面试的时候,也经常会被问及装饰器的相关知识.总感觉自己的理解很浅显,不够深刻.是时候做出改变,对Python的装饰器做 ...

  3. pytorch版本问题:AttributeError: 'module' object has no attribute '_rebuild_tensor_v2'

    用pytorch加载训练好的模型的时候遇到了如下的问题: AttributeError: 'module' object has no attribute '_rebuild_tensor_v2' 到 ...

  4. Linux cooked-mode capture 格式转换

    tcpdump抓包时,如果-i选项指定为一个网卡地址,那么抓取的数据包数据链路层是以太网头部:如果指定any,则以太网头部将被替换为linux cooked capture头部 # tcpdump - ...

  5. springboot集成shiro——使用RequiresPermissions注解无效

    在Springboot环境中继承Shiro时,使用注解@RequiresPermissions时无效 @RequestMapping("add") @RequiresPermiss ...

  6. Struts2+DAO层实现实例02——搭建DAO基本框架并与Struts2组合

    实例内容 创建DAO(Data Access Oject)接口:BaseDAO 创建其实例化类:UserDAO 用于获取数据库struts中的userinfo表中的内容 创建User的Java Bea ...

  7. android自定义SlideMenu源码详解之最简单侧滑实现

    实现原理:在一个Activity的布局中需要有两部分,一个是菜单(menu)的布局,一个是内容(content)的布局.两个布局横向排列,菜单布局在左,内容布局在右.初始化的时候将菜单布局向左偏移,以 ...

  8. c#用UpdatePanel实现接局部刷新

    通常我们看到局部刷新就会想到Ajax,但是我今天要说的是c#的一个控件,只要把服务器按钮和要刷新的区域放在该控件内就能实现局部刷新. 当然它必须和ScriptManager控件一起使用. Update ...

  9. WebIDE

    1 1 1 WebIDE 是什么? WebIDE 是 一款在线集成开发环境( Integrated Development Environment ). 开发者只需要一个浏览器就可以编写代码,并在We ...

  10. 【Luogu】P2465山贼集团(树形状压DP)

    题目链接 写了个70分暴力还挂了,第一遍提交只拿了十分……海星 首先建虚拟节点多叉树转成二叉,然后子集枚举DP 设g[x][i]是以x为根的子树内山贼集合i,x啥都不选也没贡献的时候的最大价值 f[x ...