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, 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
/*
树链剖分+线段树.
这题呵呵了.
询问字符串竟然卡cin(长记性了).
化边为点.
建树后把边的信息存在son里.
因为son只有一个father,而father可以同时有若干个son.
树剖线段树单点修改区间查询.
这题一开始W的原因是
here:query(1,pos[x],pos[y]).
应该为query(1,pos[x]+1,pos[y]).
因为我们已经把边的信息存到son里边了.
pos[x]存的是(x,fa[x])的edge.
然而我们最后查的是[x,y]的ans.
所以从x的son开始查.
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#define MAXN 100001
using namespace std;
struct edge{int v,next;}e[MAXN*2];
struct data{int l,r,lc,rc,ans;}tree[MAXN*4];
int n,m,ans,head[MAXN],cut,size[MAXN],fa[MAXN],top[MAXN],deep[MAXN],maxsize,pos[MAXN];
struct node{int x,y,z;}s[MAXN];
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*f;
}
void add(int u,int v,int x)
{
e[++cut].v=v;
e[cut].next=head[u];
head[u]=cut;
}
void build(int l,int r)
{
int k=++cut;
tree[k].l=l,tree[k].r=r;
if(l==r) return ;
int mid=(l+r)>>1;
tree[k].lc=cut+1;build(l,mid);
tree[k].rc=cut+1;build(mid+1,r);
return ;
}
void dfs1(int u)
{
size[u]=1;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if(!fa[v]) deep[v]=deep[u]+1,fa[v]=u,dfs1(v),size[u]+=size[v];
}
return ;
}
void dfs2(int u,int top1)
{
top[u]=top1;pos[u]=++maxsize;
int k=0;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if(fa[v]==u&&size[v]>size[k]) k=v;
}
if(!k) return ;
dfs2(k,top1);
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if(fa[v]==u&&v!=k) dfs2(v,v);
}
return ;
}
void change(int k,int x,int z)
{
if(tree[k].l==tree[k].r)
{
tree[k].ans=z;return ;
}
int mid=(tree[k].l+tree[k].r)>>1;
if(x<=mid) change(tree[k].lc,x,z);
else change(tree[k].rc,x,z);
tree[k].ans=max(tree[tree[k].lc].ans,tree[tree[k].rc].ans);
return ;
}
int query(int k,int l,int r)
{
if(l<=tree[k].l&&tree[k].r<=r) return tree[k].ans;
int tot=-1e9,mid=(tree[k].l+tree[k].r)>>1;
if(l<=mid) tot=max(tot,query(tree[k].lc,l,r));
if(r>mid) tot=max(tot,query(tree[k].rc,l,r));
return tot;
}
int slovequery(int x,int y)
{
ans=-1e9;
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]]) swap(x,y);
ans=max(ans,query(1,pos[top[x]],pos[x]));
x=fa[top[x]];
}
if(pos[x]>pos[y]) swap(x,y);
ans=max(ans,query(1,pos[x]+1,pos[y]));//1 W.
return ans;
}
void Clear()
{
cut=0;maxsize=0;
memset(head,0,sizeof head);
memset(size,0,sizeof size);
memset(fa,0,sizeof fa);
memset(tree,0,sizeof tree);
}
int main()
{
int x,y,z,p,q,t;
t=read();
while(t--)
{
n=read();Clear();
for(int i=1;i<=n-1;i++)
{
x=read(),y=read(),z=read();
add(x,y,z),add(y,x,z);
s[i].x=x,s[i].y=y,s[i].z=z;
}
cut=0;
build(1,n);fa[1]=1;
dfs1(1),dfs2(1,1);
for(int i=1;i<=n-1;i++)
{
x=s[i].x,y=s[i].y;
if(fa[x]==y) swap(x,y);
change(1,pos[y],s[i].z);
}
char ch[6];
while(true)
{
scanf("%s",ch);
//cin>>ch; 1T
if(ch[0]=='D') break;
x=read(),y=read();
if(ch[0]=='Q') printf("%d\n",slovequery(x,y));
else
{
p=s[x].x,q=s[x].y;
if(fa[p]==q) swap(p,q);
change(1,pos[q],y);
}
}
}
return 0;
}
Spoj Query on a tree SPOJ - QTREE(树链剖分+线段树)的更多相关文章
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
- 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 树链剖分 线段树
欢迎访问~原文出处——博客园-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 ...
随机推荐
- 剑指offer(3)——二维数组中的查找
题目: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数 思路: 首先选取数组中右上 ...
- C#从零单排上王者系列---元组
从零单排系列说明 博主最初的想法是想写个蜕茧成蝶的系列文章,后来觉得博客的表现形式很难做到连贯和系统.所以从本篇博客开始博主会选择书中比较重要和不好理解的知识点并结合自己的实际工作经验来讲解,不再是照 ...
- 使用swagger在netcorewebapi项目中自动生成文档
一.背景 随着前后端分离模式大行其道,我们需要将后端接口撰写成文档提供给前端,前端可以查看我们的接口,并测试,提高我们的开发效率,减少无效的沟通.在此情况下,通过代码自动生成文档,这种需求应运而生,s ...
- logback日志详细解析
1.为什么使用logback 内核重写.测试充分.初始化内存加载更小,这一切让logback性能和log4j相比有诸多倍的提升 logback非常自然地直接实现了slf4j,方便理解 支持自动去除旧的 ...
- ubuntu16下 Oracle安装完毕,测试是否安装成功的步骤
1.查看oracle的环境变量,在终端输入命令 echo $ORACLE_BASE echo $ORACLE_HOME echo $PATH 看输出是不是安装时设置的路径 2.开启监听器 lsnrct ...
- leetcode-21.合并有序链表 · List
题面 合并两个排序链表. 算法 创建结果链表头*res,*p指向头,当两个链表节点都不为空时,比较节点值,值小的挂在p后面,二者(p和小者)顺次后移.知道某条链表空,跳出while循环.接着,直接将不 ...
- 为什么说Java程序员必须掌握 Spring Boot ?
Spring Boot 2.0 的推出又激起了一阵学习 Spring Boot 热,那么, Spring Boot 诞生的背景是什么?Spring 企业又是基于什么样的考虑创建 Spring Boot ...
- 快速认识Python
1.数字和表达式 什么是表达式,1+2*3 就是一个表达式,这里的加号和乘号叫做运算符,1.2.3叫做操作数.1+2*3 经过计算后得到的结果是7,就1+2*3 = 7.我们可以将计算结果保存在一个变 ...
- 关于阿里云OSS上传图片之后会被旋转90度的解决办法
原文:https://www.cnblogs.com/wuhjbk/p/10133596.html 问题描述:正常的图片前端上传到oss成功之后的资源地址.在html上引用的时候被旋转了90度oss资 ...
- mongodb索引 过期索引
过期索引,指的是一段时间后会过期的索引,在索引过期后,相应的数据会被删除,这适合存储一些在一段时间之后会失效的数据,比如用户的登录信息,想要用户登录信息2天后失效,需要用户重新登录,或者存储的日志,希 ...