SPOJ VJudge QTREE - 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
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct edge{
int u,v,w,next;
}e[];
struct node{
int l,r,val;
node *lc,*rc;
}*root=NULL;
int t,n,m,head[],js,p;
int fa[],son[],dep[],top[],pos[],siz[];
// fa存他的父亲 son存他的重孩子 dep它的深度 top他所在重链的链顶
//pos在线段树中的位置 siz[v]以v为顶的子树的孩子数
void memsett()
{
js=;p=;
memset(head,,sizeof(head));
memset(e,,sizeof(e));
memset(son,,sizeof(son));
}
void add_edge(int u,int v,int w)
{
e[++js].u=u;e[js].v=v;e[js].w=w;
e[js].next=head[u];head[u]=js;
}
void dfs(int u,int f,int d)
{
fa[u]=f;dep[u]=d;siz[u]=;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if(v!=f)
{
dfs(v,u,d+);
siz[u]+=siz[v];
if(!son[u]||siz[son[u]]<siz[v])
son[u]=v;
}
}
}
void gettop(int u,int tp)
{
top[u]=tp;pos[u]=++p;
if(!son[u]) return;
gettop(son[u],tp);
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if(v!=son[u]&&v!=fa[u])
gettop(v,v);
}
}
void build(node * &pt,int l,int r)
{
pt=new(node);
pt->l=l;pt->r=r;pt->val=;
if(l==r)
{
pt->lc=pt->rc=NULL;
return ;
}
int mid=(l+r)/;
build(pt->lc,l,mid);
build(pt->rc,mid+,r);
}
void update(node * p,int ps,int val)
{
if(p->l==p->r)
{
p->val=val;return;
}
int mid=(p->l+p->r)/;
if(ps<=mid) update(p->lc,ps,val);
else update(p->rc,ps,val);
p->val=max(p->lc->val,p->rc->val);
}
int query(node * p,int l,int r)
{
if(l<=p->l&&p->r<=r)return p->val;
int mid=(p->l+p->r)/;
int ans=;
if(l<=mid)ans=max(ans,query(p->lc,l,r));
if(r>mid)ans=max(ans,query(p->rc,l,r));
return ans;
}
int find(int u,int v)
{
int tp1=top[u],tp2=top[v],ans=;
while(tp1!=tp2)
{
if(dep[tp1]<dep[tp2])
{
swap(tp1,tp2);swap(u,v);
}
ans=max(ans,query(root,pos[tp1],pos[u]));
u=fa[tp1];tp1=top[u];
}
if(u==v) return ans;
if(dep[u]>dep[v]) swap(u,v);
return max(ans,query(root,pos[u]+,pos[v]));
}
int main()
{
scanf("%d",&t);
while(t--)
{
memsett();
scanf("%d",&n);
for(int i=;i<=n-;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add_edge(x,y,z);add_edge(y,x,z);
}
dfs(,,);
gettop(,);
build(root,,p);
for(int i=;i<*n-;i+=)// 建边表时见了两遍
{
if(dep[e[i].v]<dep[e[i].u]) swap(e[i].v,e[i].u);// 让v在下面
update(root,pos[e[i].v],e[i].w);
}
char s[];int u,v;
while(scanf("%s",s)==)
{
if(s[]=='D') break;
scanf("%d%d",&u,&v);
if(s[]=='Q') printf("%d\n",find(u,v));// 查询从u到v所经过的最大边权
else update(root,pos[e[u*-].v],v);// 将第u条边的权值修改为v
}
}
return ;
}
思路:树链剖分基础题
SPOJ VJudge QTREE - Query on a tree的更多相关文章
- spoj 375 QTREE - Query on a tree 树链剖分
题目链接 给一棵树, 每条边有权值, 两种操作, 一种是将一条边的权值改变, 一种是询问u到v路径上最大的边的权值. 树链剖分模板. #include <iostream> #includ ...
- SPOJ 375 QTREE - Query on a tree
思路 注意本题只能用C,不能用C++ 其他的都和上一题一样 代码 #include <stdio.h> #include <string.h> #define MAXN 100 ...
- 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 ...
- QTREE - Query on a tree
QTREE - Query on a tree 题目链接:http://www.spoj.com/problems/QTREE/ 参考博客:http://blog.sina.com.cn/s/blog ...
- SP375 QTREE - Query on a tree (树剖)
题目 SP375 QTREE - Query on a tree 解析 也就是个蓝题,因为比较长 树剖裸题(基本上),单点修改,链上查询. 顺便来说一下链上操作时如何将边上的操作转化为点上的操作: 可 ...
- spoj QTREE - Query on a tree(树链剖分+线段树单点更新,区间查询)
传送门:Problem QTREE https://www.cnblogs.com/violet-acmer/p/9711441.html 题解: 树链剖分的模板题,看代码比看文字解析理解来的快~~~ ...
- SPOJ QTREE Query on a tree ——树链剖分 线段树
[题目分析] 垃圾vjudge又挂了. 树链剖分裸题. 垃圾spoj,交了好几次,基本没改动却过了. [代码](自带常数,是别人的2倍左右) #include <cstdio> #incl ...
- SPOJ QTREE Query on a tree --树链剖分
题意:给一棵树,每次更新某条边或者查询u->v路径上的边权最大值. 解法:做过上一题,这题就没太大问题了,以终点的标号作为边的标号,因为dfs只能给点分配位置,而一棵树每条树边的终点只有一个. ...
- SPOJ QTREE Query on a tree VI
You are given a tree (an acyclic undirected connected graph) with n nodes. The tree nodes are number ...
随机推荐
- P2712 摄像头
题目描述 食品店里有n个摄像头,这种摄像头很笨拙,只能拍摄到固定位置.现有一群胆大妄为的松鼠想要抢劫食品店,为了不让摄像头拍下他们犯罪的证据,他们抢劫前的第一件事就是砸毁这些摄像头. 为了便于砸毁摄像 ...
- Understanding Scroll Views 深入理解 scroll view 读书笔记
Understanding Scroll Views 深入理解 scroll view 读书笔记 It may be hard to believe, but a UIScrollView is ...
- ubuntu下安装php-curl扩展
查找包 apt-cache是linux下的一个apt软件包管理工具,它可查询apt的二进制软件包缓存文件.APT包管理的大多数信息查询功能都可以由apt-cache命令实现,通过apt-cache命令 ...
- IOS之pageControl
用户点击页面控件,会触发UIControlEventValueChanged事件,并启动设置为控件动作的任何方法.可以通过调用currentPage查询控件的新值,并通过调整numberOfPages ...
- 微信小程序开发系列教程三:微信小程序的调试方法
微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 这个教程的前两篇文章,介绍了如何用下图所示的微信开发者工具自动生成一个Hel ...
- SDUT_2146:最小子序列和
题目描述 给你一个长为n(10<=n<=10000)的数组,数组中的每一个数大于等于1小于等于1000000.请你找出一个长为k(1<=k<=1000)的子序列.找序列时,假如 ...
- 关于websocket的代码,实现发送信息和监听信息(前端 后端(node.js))
文件结构 node.js代码 // 需要HTTP 模块来启动服务器和Socket.IOvar http= require('http');var fs = require('fs');// 在8080 ...
- 获取指定点的RGB值
实现效果: 知识运用: Color对象的RGB属性 实现代码: private void button1_Click(object sender, EventArgs e) { OpenFileDia ...
- OPENCV3 命名空间等变化
CV_VERSION 表示的opencv的版本号 命名空间变化: 可以通过增加 #include <cv.h> 解决 1 直接去掉CV_ 前缀 1) nameWindow 函数 C ...
- PHP13 会话控制
学习要点 会话控制使用的意义 用户跟踪方式 Cookie的设置.读取以及删除 Session的设置.读取以及删除 自定义session处理方式 会话控制 什么是会话控制 实现服务器跟踪同一个客户端的连 ...