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 ...
随机推荐
- zencart 显示Deprecated: Assigning the return value of new by reference is deprecated
很多朋友的php程序当php的版本升级到5.3以后,会出现"Deprecated: Assigning the return value of new by reference is dep ...
- Angular7和PrimeNg集成
常规操作之后,随便加了一个控件发现报错了.错误信息看起来是不能识别PrimeNg的组件,经过一番折腾发现.因为用到了ngModel,需要导入FormsModule.因为新建的工程没有导入,导入之后就好 ...
- 十一、S3C2440 裸机 — GPIO
11.1 GPIO 介绍 11.1.1 GPIO 管脚 GPIO 即是输入输出端口,S3C2440A 包含了 130 个多功能输入/输出口引脚并且它们为如下显示的八个端口: 端口 A(GPA):25 ...
- Java基本的程序结构设计 大数操作
大数操作 BigInteger 不可变的任意精度的整数.所有操作中,都以二进制补码形式表示 BigInteger(如 Java 的基本整数类型).BigInteger 提供所有 Java 的基本整数操 ...
- Python修炼之路-异常
异常处理 在程序出现bug时一般不会将错误信息直接显示给用户,而是可以自定义显示内容或处理. 常见异常 AttributeError # 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性 ...
- Notepad++技巧
1 正则表达式的查找和替换,例如删除每行开始的数字ctrl+H, ^\d\d\d:null 2 删除所有的空行: TextFX插件->Edit->Delete Blank Lines 3 ...
- 【leetcode】1207. Unique Number of Occurrences
题目如下: Given an array of integers arr, write a function that returns true if and only if the number o ...
- cocos2d 15款游戏源码
https://blog.csdn.net/jailman/article/details/78678972
- Tarjan算法初步
一.前置知识: 强连通分量:有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(stron ...
- wannafly 练习赛11 E 求最值(平面最近点对)
链接:https://www.nowcoder.com/acm/contest/59/E 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K 64bit ...