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--树链剖分的更多相关文章

  1. SPOJ375.QTREE树链剖分

    题意:一个树,a b c 代表a--b边的权值为c.CHANGE x y  把输入的第x条边的权值改为y,QUERY x y 查询x--y路径上边的权值的最大值. 第一次写树链剖分,其实树链剖分只能说 ...

  2. QTREE 树链剖分---模板 spoj QTREE

    <树链剖分及其应用> 一文讲得非常清楚,我一早上就把他学会了并且A了这题的入门题. spoj QTREE 题目: 给出一棵树,有两种操作: 1.修改一条边的边权. 2.询问节点a到b的最大 ...

  3. SPOJ QTREE 树链剖分

    树链剖分的第一题,易懂,注意这里是边. #include<queue> #include<stack> #include<cmath> #include<cs ...

  4. 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, ...

  5. 【学术篇】SPOJ QTREE 树链剖分

    发现链剖这东西好久不写想一遍写对是有难度的.. 果然是熟能生巧吧.. WC的dalao们都回来了 然后就用WC的毒瘤题荼毒了我们一波, 本来想打个T1 44分暴力 然后好像是特判写挂了还是怎么的就只能 ...

  6. Cogs 1672. [SPOJ375 QTREE]难存的情缘 LCT,树链剖分,填坑计划

    题目:http://cojs.tk/cogs/problem/problem.php?pid=1672 1672. [SPOJ375 QTREE]难存的情缘 ★★★☆   输入文件:qtree.in  ...

  7. [SPOJ375]QTREE - Query on a tree【树链剖分】

    题目描述 给你一棵树,两种操作. 修改边权,查找边权的最大值. 分析 我们都知道,树链剖分能够维护点权. 而且每一条边只有一个,且唯一对应一个儿子节点,那么就把信息放到这个儿子节点上. 注意,lca的 ...

  8. spoj QTREE - Query on a tree(树链剖分+线段树单点更新,区间查询)

    传送门:Problem QTREE https://www.cnblogs.com/violet-acmer/p/9711441.html 题解: 树链剖分的模板题,看代码比看文字解析理解来的快~~~ ...

  9. 树链剖分边权模板spoj375

    树链剖分是树分解成多条链来解决树上两点之间的路径上的问题 如何求出树链:第一次dfs求出树上每个结点的大小和深度和最大的儿子,第二次dfs就能将最大的儿子串起来并hash(映射)到线段树上(或者其他数 ...

  10. 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 ...

随机推荐

  1. 最简单的Android项目(添加jar文件)

    如果项目需要引用第三方jar文件,需要对编译命令做一些改动. 首先在项目根目录创建libs目录,将需要的jar文件拷贝到里面. 编译过程中有两步需要改动. 编译java源文件时,需要添加class p ...

  2. 清北学堂提高组突破营游记day4

    今天主攻图论. 对于这道题,30分做法是暴力搜索全部来判断是否有异样. 对于满分做法,利用带权并查集.? 又带我们串了一边LCA 安利个人LCA博客. spfa代码.原理:循环队列. 然后是floyd ...

  3. LOJ-6277-数列分块入门1(分块)

    链接: https://loj.ac/problem/6277 题意: 给出一个长为 的数列,以及 个操作,操作涉及区间加法,单点查值. 思路: 线段树可以解决,用来学习分块. 分块概念就是,将序列分 ...

  4. 算法——二进制解决N皇后(超级酷炫o((>ω< ))o

    先贴代码: public class Solution { void NQueen(int N, int row, int col, int pie, int na, int[] res) { if ...

  5. Winserver-禁止程序启动

    注册表限制程序启动 经测试,可以阻止手动启动,但在job中还是会有启动的进程,这个待确定. run→regedit 添加程序只写exe名就行 手动不能运行了

  6. vue学习-day03(动画,组件)

    目录: 1.品牌列表-从数据库获取列表    2.品牌列表-完成添加功能    3.品牌列表-完成删除功能    4.品牌列表-全局配置数据接口的根域名    5.品牌列表-全局配置emulateJS ...

  7. 网页设计之js

    1.JavaScript概述 javaScript与ECMAScript的相爱相杀 1996年11月,JavaScript的创造者--Netscape公司,决定将JavaScript提交给国际标准化组 ...

  8. java语言课堂动手动脑

    1 运行 TestInherits.java 示例,观察输出,注意总结父类与子类之间构造方法的调用关系修改Parent构造方法的代码,显式调用GrandParent的另一个构造函数,注意这句调用代码是 ...

  9. 南京网络赛 E K Sum

    K Sum 终于过了这玩意啊啊啊==== 莫比乌斯反演,杜教筛,各种分块,积性函数怎么线性递推还很迷==,得继续研究研究 #include<bits/stdc++.h> using nam ...

  10. DVWA--XSS(反射型)

    0X01爱之初介绍 虽然XSS已经做了两节了 但是还是还是简单解释一下 前言:跨站脚本(Cross-Site Scripting,XSS)是一种经常出现在Web应用程序中的计算机安全漏洞,是由于Web ...