Spoj375 Qtree--树链剖分
Spoj375 Qtree
给一棵共有 n(n · 10000) 个结点的树, 每条边都有一个权值, 要求维护一个数据结构, 支持如下操作:
1. 修改某条边的权值;
2. 询问某两个结点之间的唯一通路上的最大边权.
其中操作的总次数为 q.
Sample Input
3
1 2 1
2 3 2
QUERY 1 2
CHANGE 1 3
QUERY 1 2
DONE
Sample Output
1
3
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int sum,maxx,n,m,f[30001],pre[100001],nxt[100001],h[30001],now,size[100001],dep[100001],id[30001],top[30001],cnt,y[30001],z[30001],x[30001];
struct oo
{
int a,b,mx;
}
s[100001];
char p[9];
void dfs(int x)
{
size[x]=1;
for(int i=h[x];i;i=nxt[i])
{
if(pre[i]==f[x])
continue;
dep[pre[i]]=dep[x]+1;
f[pre[i]]=x;
dfs(pre[i]);
size[x]+=size[pre[i]];
}
}
void dfs2(int x,int f)
{
int k=0;
id[x]=++cnt;//x在线段树中的位置
top[x]=f;//标记top结记
for(int i=h[x];i;i=nxt[i]) // 找出重儿子
if(size[pre[i]]>size[k]&&dep[pre[i]]>dep[x])
k=pre[i];
if(!k)
return ;
dfs2(k,f);
for(int i=h[x];i;i=nxt[i])
if(dep[pre[i]]>dep[x]&&pre[i]!=k)
dfs2(pre[i],pre[i]);
}
void ins(int x,int y)
{
pre[++now]=y;
nxt[now]=h[x];
h[x]=now;
}
void build(int x,int l,int r)
{
s[x].a=l;
s[x].b=r;
if(l==r)
{
s[x].mx=-1e9;
return ;
}
build(x<<1,l,l+r>>1);
build(x<<1|1,(l+r>>1)+1,r);
s[x].mx=max(s[x<<1].mx,s[x<<1|1].mx);
}
void get(int x,int l,int r)
{
if(s[x].a>=l&&r>=s[x].b)
maxx=max(s[x].mx,maxx);
else
{
int mid=s[x].a+s[x].b>>1;
if(l<=mid)
get(x<<1,l,r);
if(r>mid)
get(x<<1|1,l,r);
}
}
void qmax(int x,int y)
{
maxx=-1e9;
while(top[x]!=top[y])//当没有在一条重链上时
{
if(dep[top[x]]<dep[top[y]])
swap(x,y);
get(1,id[top[x]],id[x]);
x=f[top[x]];
}
if(id[x]>id[y])
swap(x,y);
get(1,id[x]+1,id[y]);
}
void change(int x,int l,int v)
{
if(s[x].a==s[x].b)
{
s[x].mx=v;
return ;
}
int mid=s[x].a+s[x].b>>1;
if(l<=mid)
change(x<<1,l,v);
else
change(x<<1|1,l,v);
s[x].mx=max(s[x<<1].mx,s[x<<1|1].mx);
}
int T;
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
memset(h,0,sizeof h);
now=0;cnt=0;
for(int i=1;i<n;i++)
{
scanf("%d%d%d",&x[i],&y[i],&z[i]);
ins(x[i],y[i]);
ins(y[i],x[i]);
}
dfs(1);
dfs2(1,1);
build(1,1,n);
for(int i=1;i<n;i++)
{
int a=id[x[i]],b=id[y[i]];
if(dep[x[i]]>dep[y[i]])
//将边权放到点上,要放到这条边的儿子点上
//因为某个点可以会有多个子结点,放父亲点,就会出问题了
change(1,a,z[i]),z[i]=a;//记下第i条边在线段树中的位置 else
change(1,b,z[i]),z[i]=b;
}
while(1)
{
int a,b;
scanf("%s",p+1);
if(p[1]=='Q')
{
scanf("%d%d",&a,&b);
qmax(a,b);
printf("%d\n",maxx);
}
if(p[1]=='D')break;
if(p[1]=='C')
scanf("%d%d",&a,&b),change(1,z[a],b);
}
}
}
Spoj375 Qtree--树链剖分的更多相关文章
- SPOJ375.QTREE树链剖分
题意:一个树,a b c 代表a--b边的权值为c.CHANGE x y 把输入的第x条边的权值改为y,QUERY x y 查询x--y路径上边的权值的最大值. 第一次写树链剖分,其实树链剖分只能说 ...
- QTREE 树链剖分---模板 spoj QTREE
<树链剖分及其应用> 一文讲得非常清楚,我一早上就把他学会了并且A了这题的入门题. spoj QTREE 题目: 给出一棵树,有两种操作: 1.修改一条边的边权. 2.询问节点a到b的最大 ...
- SPOJ QTREE 树链剖分
树链剖分的第一题,易懂,注意这里是边. #include<queue> #include<stack> #include<cmath> #include<cs ...
- 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, ...
- 【学术篇】SPOJ QTREE 树链剖分
发现链剖这东西好久不写想一遍写对是有难度的.. 果然是熟能生巧吧.. WC的dalao们都回来了 然后就用WC的毒瘤题荼毒了我们一波, 本来想打个T1 44分暴力 然后好像是特判写挂了还是怎么的就只能 ...
- Cogs 1672. [SPOJ375 QTREE]难存的情缘 LCT,树链剖分,填坑计划
题目:http://cojs.tk/cogs/problem/problem.php?pid=1672 1672. [SPOJ375 QTREE]难存的情缘 ★★★☆ 输入文件:qtree.in ...
- [SPOJ375]QTREE - Query on a tree【树链剖分】
题目描述 给你一棵树,两种操作. 修改边权,查找边权的最大值. 分析 我们都知道,树链剖分能够维护点权. 而且每一条边只有一个,且唯一对应一个儿子节点,那么就把信息放到这个儿子节点上. 注意,lca的 ...
- spoj QTREE - Query on a tree(树链剖分+线段树单点更新,区间查询)
传送门:Problem QTREE https://www.cnblogs.com/violet-acmer/p/9711441.html 题解: 树链剖分的模板题,看代码比看文字解析理解来的快~~~ ...
- 树链剖分边权模板spoj375
树链剖分是树分解成多条链来解决树上两点之间的路径上的问题 如何求出树链:第一次dfs求出树上每个结点的大小和深度和最大的儿子,第二次dfs就能将最大的儿子串起来并hash(映射)到线段树上(或者其他数 ...
- 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 ...
随机推荐
- 校内题目T2695 桶哥的问题——吃桶
同T2一样外校蒟蒻可能没看过: 题目描述: 题目背景 @桶哥 桶哥的桶没有送完. 题目描述 桶哥的桶没有送完,他还有n个桶.他决定把这些桶吃掉.他的每一个桶两个属性:种类aia_iai和美味值bib ...
- js - 基础 之 预编译总结
js运行步骤 语法解析(检查有无语法错误) 预编译 解释运行(将 js 翻译成计算机识别的语言(0.1组成),翻译一行执行一行) 预编译 [全局]: 创建 GO( Grobal Object ) 对象 ...
- Python中绘制箭头
以两个点为例,其中起点为点(1,2),终点为点(3,4) import matplotlib.pyplot as plt def drawArrow(A,B): fig = plt.figure() ...
- 使用python开发WebService
使用python开发WebService 分类: web linux2009-03-30 11:36 6621人阅读 评论(1) 收藏 举报 webservicepythonsoapimportecl ...
- .net reactor 加密混淆使用办法
https://www.cnblogs.com/bile/p/10250888.html 概述:安装了.net reactor之后,可以在安装目录下找到帮助文档REACTOR_HELP.chm,目前没 ...
- 一个用于格式化和处理数字的javascript库----Numeral.js
npm地址:https://www.npmjs.com/package/numeral 1.转化成百分比: numeral(num).format('0.00%')
- springmvc/springboot开发restful API
非rest的url写法: 查询 GET /user/query?name=tom 详情 GET /user/getinfo? 创建 POST /user/create?name=tom 修改 POST ...
- 11.Linux date命令的用法
date命令常的日常应用 修改时间 date -s “2008/05/23 19:20″ 打包文件 tar zcvf log-$(date +$F).gz /home/admin/logs 同步阿 ...
- java+struts上传文件夹文件
这里只写后端的代码,基本的思想就是,前端将文件分片,然后每次访问上传接口的时候,向后端传入参数:当前为第几块文件,和分片总数 下面直接贴代码吧,一些难懂的我大部分都加上注释了: 上传文件实体类: 看得 ...
- 为什么C++中只有指针和引用才能实现多态?
代码: class A { public: virtual void Debug(){} }; class B:public A { public: virtual void Debug(){} }; ...