spoj 375 Query on a tree(树链剖分,线段树)
Time Limit: 851MS | Memory Limit: 1572864KB | 64bit IO Format: %lld & %llu |
Description
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.sina.com.cn/s/blog_6974c8b20100zc61.html
【代码】
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std; const int N = +; struct Edge { int u,v,w; };
vector<int> G[N];
vector<Edge> es;
int n,z,root,d[N][];
int fa[N],siz[N],dep[N],son[N],w[N],top[N];
//fa为父节点 siz为子树大小 dep为节点深度
//son代表重儿子 w为u与fa[u]在线段树中的位置 top代表所属重链的顶端
//z为线段树大小 void adde(int u,int v,int w) {
es.push_back((Edge){u,v,w});
int m=es.size();
G[u].push_back(m-);
} void dfs(int u) { //->siz[] son[] fa[]
siz[u]=; son[u]=;
for(int i=;i<G[u].size();i++) {
int v=es[G[u][i]].v;
if(v!=fa[u]) {
fa[v]=u;
dep[v]=dep[u]+;
dfs(v);
if(siz[v]>siz[son[u]]) son[u]=v;
siz[u]+=siz[v];
}
}
}
void build_tree(int u,int tp) { //son[] -> top[] w[]
w[u]=++z; top[u]=tp;
if(son[u]) build_tree(son[u],top[u]);
for(int i=;i<G[u].size();i++) {
int v=es[G[u][i]].v;
if(v!=son[u] && v!=fa[u]) build_tree(v,v);
}
} int tree[N];
void update(int u,int L,int R,int loc,int x) {
if(loc<L || R<loc) return ;
if(L==R) { tree[u]=x; return ; }
int M=L+(R-L)/ , lc=u*,rc=lc+;
update(lc,L,M,loc,x);
update(rc,M+,R,loc,x);
tree[u]=max(tree[lc],tree[rc]);
}
int query(int u,int L,int R,int l,int r) {
if(R<l || L>r) return ;
if(l<=L && R<=r) return tree[u];
int M=L+(R-L)/;
return max(query(u*,L,M,l,r),query(u*+,M+,R,l,r));
}
int find(int u,int v) {
int f1=top[u] , f2=top[v] , ans=;
while(f1!=f2) { //直到移动到同一重链
if(dep[f1]<dep[f2])
swap(f1,f2) , swap(u,v);
ans=max(ans,query(,,z,w[f1],w[u])); //在重链上移动同时统计
u=fa[f1] , f1=top[u];
}
if(u==v) return ans;
if(dep[u]>dep[v]) swap(u,v);
return max(ans,query(,,z,w[son[u]],w[v])); //uv之间统计
} void init() {
scanf("%d",&n);
es.clear();
for(int i=;i<=n;i++) G[i].clear();
root=(n+)/;
fa[root]=dep[root]=z=;
memset(siz,,sizeof(siz));
memset(tree,,sizeof(tree));
int u,v,c;
for(int i=;i<n;i++) {
scanf("%d%d%d",&u,&v,&c);
d[i][]=u , d[i][]=v , d[i][]=c;
adde(u,v,c) , adde(v,u,c);
}
dfs(root);
build_tree(root,root);
for(int i=;i<n;i++) {
if(dep[d[i][]]>dep[d[i][]]) swap(d[i][],d[i][]);
update(,,z,w[d[i][]],d[i][]);
}
}
void solve() {
char s[];
int u,v;
while(scanf("%s",s)== && s[]!='D') {
scanf("%d%d",&u,&v);
if(s[]=='Q') printf("%d\n",find(u,v));
else update(,,z,w[d[u][]],v);
}
} int main() {
int T;
scanf("%d",&T);
while(T--) {
init();
solve();
}
return ;
}
spoj 375 Query on a tree(树链剖分,线段树)的更多相关文章
- Spoj Query on a tree SPOJ - QTREE(树链剖分+线段树)
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...
- Aizu 2450 Do use segment tree 树链剖分+线段树
Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
- POJ3237 Tree 树链剖分 线段树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ3237 题意概括 Description 给你由N个结点组成的树.树的节点被编号为1到N,边被编号为1 ...
- 【CF725G】Messages on a Tree 树链剖分+线段树
[CF725G]Messages on a Tree 题意:给你一棵n+1个节点的树,0号节点是树根,在编号为1到n的节点上各有一只跳蚤,0号节点是跳蚤国王.现在一些跳蚤要给跳蚤国王发信息.具体的信息 ...
- Water Tree CodeForces 343D 树链剖分+线段树
Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )
BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...
- Aragorn's Story 树链剖分+线段树 && 树链剖分+树状数组
Aragorn's Story 来源:http://www.fjutacm.com/Problem.jsp?pid=2710来源:http://acm.hdu.edu.cn/showproblem.p ...
随机推荐
- Server.MapPath()获取绝对路径
1. Server.MapPath("/") 应用程序根目录所在的位置 如 C:\Inetpub\wwwroot\ 2.Server.MapPath("./&qu ...
- JavaScript之动画3
给一个div添加颜色,使其产生渐变效果,我们设置index为变量,使用setInterval函数方法改变rgb颜色值. window.onload = function(){ var boxDom = ...
- Cocos2d-JS事件处理机制
在很多图形用户技术中,事件处理机制一般都有三个重要的角色:事件.事件源和事件处理者.事件源是事件发生的场所,通常就是各个视图或控件,事件处理者是接收事件并对其进行处理的一段程序.事件处理机制中三个角色 ...
- 返璞归真vc++之字符类型
在今天,大量使用java与.net的程序员已经很少去真实了解字符的底层表达,但是使用VC++编程,对字符的处理却非常慎重,刚学习vc++肯定会为其中的字符类型给晕头转向,今天本人学习第一节,从字符开始 ...
- 链接与ELF文件格式的复习
在这里复习一下链接的知识: 什么是链接(linking):把源代码形成的模块独立编译后组装成一个整体的的过程叫做链接. 链接主要过程包括:地址和空间分配(address and storage all ...
- 从基础知识到重写Spring的Bean工厂中学习java的工厂模式
1.静态工厂模式其他对象不能直接通过new得到某个类,而是通过调用getInstance()方法得到该类的对象这样,就可以控制类的产生过程.顺带提一下单例模式和多例模式: 单例模式是指控制其他对象获 ...
- 【Qt】QDialog之屏蔽Esc键【转】
简述 Qt中Esc键会在一些控件中默认的进行一些事件的触发,比如:QDialog,按下Esc键窗口消失.大多数情况下,我们不需要这么做,那么就需要对默认事件进行屏蔽. 简述 源码分析 事件过滤器 事件 ...
- 跟着PHP100第一季学写一个CMS(11-20)
PS.刚发现IE并不兼容,有点悲剧 cms1.1密码处理 1.小知识:sha1($_answer) //加密为40位,不知道能不能破解 2.小知识:mysql_real_escape_string( ...
- 使用dxNavBar动态创建应用程序菜单
一.如何动态创建dxNavBar内容: function TMain.GetAcitonByCaption(const aCategory,aCaption: string): Integer; va ...
- python学习第三天第一部分
字典 1.字典的定义和规则: 定义:{key1:value1,key2:value2} key 的定义规则:1.必须是不可变的(数字.字符串.元组):2.必须是唯一的, value的定义规则:任意类型 ...