SPOJ375Query on a tree I(树剖+线段树)(询问边)
ι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
题意:
对于一棵树,有如下两种操作;
- 询问u,v两点间的最短路上权值最大的边。
- 更改某条边的权值。
思路:
树剖基础题,大家都会,而我刚刚学,所以就不啰嗦了。
如果是更新点,查询点,可能好写点。而这里是对边进行处理,写半天把自己搅混了。。。
代码里是这样处理的:
- 对于每条边的两个顶点u,v,距离root远的是u,不然交换即可。假设这条边是i,用tid[u]表示这条边在线段树中对应的位置。即tid x表示x和父亲这条边在线段树中的位置。用时间戳tim++保证了root一下的x才有对应的tid;
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstring>
const int maxn=;
using namespace std;
int e[maxn][];
int dpt[maxn],son[maxn],fa[maxn];
int Laxt[maxn],Next[maxn],To[maxn],cnt;
int sz[maxn],tid[maxn],top[maxn],tim;//树剖
int Max[maxn],Rank[maxn],n;//线段树
//tid[v]表示v与其父亲节点的连边在线段树中的位置 即time'id
struct TC
{
int lowbit(int x) { return x&(-x);}
void init()
{
cnt=; tim=;
memset(Laxt,,sizeof(Laxt));
memset(Max,,sizeof(Max));
memset(son,,sizeof(son));
}
void add_edge(int u,int v)
{
Next[++cnt]=Laxt[u];
Laxt[u]=cnt; To[cnt]=v;
}
int dfs1(int u,int pre)//得到dpt,fa,son,sz
{
fa[u]=pre;dpt[u]=dpt[pre]+;sz[u]=;
for(int i=Laxt[u];i;i=Next[i]){
int v=To[i];
if(v!=pre){
dfs1(v,u); sz[u]+=sz[v];
if(!son[u]||sz[v]>sz[son[u]]) son[u]=v;
}
}
}
void dfs2(int u,int Top)//得到边在线段树中的位置。
{
top[u]=Top; tid[u]=tim++; Rank[tid[u]]=u;//是tim++,而不是++tim,从而把root排除,弱保存点是后者
if(!son[u]) return ;
dfs2(son[u],Top);
for(int i=Laxt[u];i;i=Next[i]){
int v=To[i];
if(v!=fa[u]&&v!=son[u]) {
dfs2(v,v);//这里不再是Top了,换链了。
}
}
}
int update(int Now,int L,int R,int pos,int num)
{
if(L==pos&&R==pos) return Max[Now]=num;
int Mid=(L+R)>>;//下面注意不要丢掉return,WA了两发。不然多写个push_up也可以。
if(pos<=Mid) return Max[Now]=max(update(Now<<,L,Mid,pos,num),Max[Now<<|]);
else return Max[Now]=max(update(Now<<|,Mid+,R,pos,num),Max[Now<<]);
}
void Make_tree()
{
int u,v;
for(int i=;i<n;i++){
scanf("%d%d%d",&e[i][],&e[i][],&e[i][]);
add_edge(e[i][],e[i][]);
add_edge(e[i][],e[i][]);
}
dfs1(,);
dfs2(,);
for(int i=;i<n; i++){//单点更新建树
if(dpt[e[i][]]>dpt[e[i][]]) swap(e[i][],e[i][]);
update(,,n-,tid[e[i][]],e[i][]);
}
}
int get_max(int Now,int L,int R,int l,int r)
{
if(L>=l&&R<=r) return Max[Now];
int Mid=(L+R)>>;
if(Mid>=r) return get_max(Now<<,L,Mid,l,r);
else if(Mid+<=l) return get_max(Now<<|,Mid+,R,l,r);
else return max(get_max(Now<<,L,Mid,l,r),get_max(Now<<|,Mid+,R,l,r));
}
void Query()
{
int u,v; scanf("%d%d",&u,&v);
int f1=top[u],f2=top[v];
int ans=;
while(f1 != f2){
if(dpt[f1] < dpt[f2]){
swap(f1,f2); swap(u,v);
}
ans=max(ans,get_max(,,n-,tid[f1],tid[u]));
u=fa[f1]; f1=top[u];
}
if(u!=v){
if(dpt[u]>dpt[v]) swap(u,v);
ans=max(ans,get_max(,,n-,tid[son[u]],tid[v]));
}
printf("%d\n",ans);
}
void Change()
{
int u,w; scanf("%d%d",&u,&w);
update(,,n-,tid[e[u][]],w);
}
}Tc;
int main()
{
int T; char c[];
scanf("%d",&T);
while(T--){
Tc.init();
scanf("%d",&n);
Tc.Make_tree();
while(~scanf("%s",&c)){
if(c[]=='D') break;
else if(c[]=='Q') Tc.Query();
else Tc.Change();
}
} return ;
}
SPOJ375Query on a tree I(树剖+线段树)(询问边)的更多相关文章
- POJ3237 Tree(树剖+线段树+lazy标记)
You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbe ...
- BZOJ_2238_Mst_树剖+线段树
BZOJ_2238_Mst_树剖+线段树 Description 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影 ...
- BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树
BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为 ...
- BZOJ_2157_旅游_树剖+线段树
BZOJ_2157_旅游_树剖+线段树 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...
- 【BZOJ5210】最大连通子块和 树剖线段树+动态DP
[BZOJ5210]最大连通子块和 Description 给出一棵n个点.以1为根的有根树,点有点权.要求支持如下两种操作: M x y:将点x的点权改为y: Q x:求以x为根的子树的最大连通子块 ...
- [LNOI2014]LCA(树剖+线段树)
\(\%\%\% Fading\) 此题是他第一道黑题(我的第一道黑题是蒲公英) 一直不敢开,后来发现是差分一下,将询问离线,树剖+线段树维护即可 \(Code\ Below:\) #include ...
- [CF1007D]Ants[2-SAT+树剖+线段树优化建图]
题意 我们用路径 \((u, v)\) 表示一棵树上从结点 \(u\) 到结点 \(v\) 的最短路径. 给定一棵由 \(n\) 个结点构成的树.你需要用 \(m\) 种不同的颜色为这棵树的树边染色, ...
- LOJ#3088. 「GXOI / GZOI2019」旧词(树剖+线段树)
题面 传送门 题解 先考虑\(k=1\)的情况,我们可以离线处理,从小到大对于每一个\(i\),令\(1\)到\(i\)的路径上每个节点权值增加\(1\),然后对于所有\(x=i\)的询问查一下\(y ...
- BZOJ3531-[Sdoi2014]旅行(树剖+线段树动态开点)
传送门 完了今天才知道原来线段树的动态开点和主席树是不一样的啊 我们先考虑没有宗教信仰的限制,那么就是一个很明显的树剖+线段树,路径查询最大值以及路径和 然后有了宗教信仰的限制该怎么做呢? 先考虑暴力 ...
- 【bzoj4699】树上的最短路(树剖+线段树优化建图)
题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...
随机推荐
- 【BZOJ3707】圈地 几何
[BZOJ3707]圈地 Description 2维平面上有n个木桩,黄学长有一次圈地的机会并得到圈到的土地,为了体现他的高风亮节,他要使他圈到的土地面积尽量小.圈地需要圈一个至少3个点的多边形,多 ...
- Delphi 64与32位的差异
Delphi 64与32位的差异 最近,Delphi推出了64位预览版本, 我做为一个忠实的Delphier, 看到这消息后,第一时间学习,并写下这个做为以后的参考资料. 相同点: 在Delphi ...
- restful规范和restframework框架
什么是接口? 接口可以理解为url就是接口. 那么在其他语言里面接口也可以是约束类 restful规范是什么? RESTful是目前最流行的一种互联网软件架构.它结构清晰.符合标准.易于理解.扩展方便 ...
- eclispse + tomcat 启动是不加载项目的解决办法
有一个java spring的项目一直好好的,突然一天不能启动了.eclipse的console没有报任何错误,相关的server配置也没有问题,经过一翻折腾顺便还把eclipse从indigo升级到 ...
- 【C语言】Linux C调用系统命令
最近研究深度学习,做视频分析和检测,用到C语言,以前都是写python的,不过没关系,计算机语言都是相通的,差不多原理是一样的,只是语法不太一样. 下面介绍linux C语言种调用本地命令,访问一个地 ...
- eclipse 修改 JDK中的src.zip的路径
http://blog.sina.com.cn/s/blog_54a1bca7010112fb.html http://www.douban.com/note/211369821/ 1.点 “wind ...
- LeetCode:三个数的最大乘积【628】
LeetCode:三个数的最大乘积[628] 题目描述 给定一个整型数组,在数组中找出由三个数组成的最大乘积,并输出这个乘积. 示例 1: 输入: [1,2,3] 输出: 6 示例 2: 输入: [1 ...
- iOS UITableViewCell UITableVIewController 纯代码开发
iOS UITableViewCell UITableVIewController 纯代码开发 <原创> .纯代码 自定义UITableViewCell 直接上代码 ////// #imp ...
- JavaScript 从对象 new 说起,简单理解 this/call/apply
new 创建一个新对象: 将构造函数的作用域赋给新对象(因此this就指向了这个新对象): 执行构造函数中的代码(为这个新对象添加属性): 返回新对象 用代码描述的话(先别管proyotype, a ...
- selenium主要功能封装
最近实习需要使用selenium这一自动化工具对公司的运维监控系统进行自动化爬取数据,编写代码过程中负责带我的杰哥让我参考借鉴他们公司外包的运维监控系统代码,在项目中我看到了对selenium主要各功 ...