SPOJ 375 QTREE
题目链接:传送门
题目大意:给一棵无根树,树边有权值,有很多次操作,QUERY代表询问从 x 到 y 路径上的边的最大
权值,CHANGE代表改变按输入顺序第 x 条边的权值为 y。 对于每个QUERY,输出一个答案。
题目思路:树链剖分(第一次学树链,还有点云里雾里的)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <cctype>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <climits>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define fi first
#define se second
#define ping(x,y) ((x-y)*(x-y))
#define mst(x,y) memset(x,y,sizeof(x))
#define mcp(x,y) memcpy(x,y,sizeof(y))
using namespace std;
#define gamma 0.5772156649015328606065120
#define MOD 1000000007
#define inf 0x3f3f3f3f
#define N 10050
#define maxn 30010
typedef pair<int,int> PII;
typedef long long LL;
LL read(){
LL x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
} int n,m,k,head[N],hcnt,rt;
char str[];
struct Node{
int to,nxt,v;
}node[maxn];
struct Edge{
int x,y,v;
}edge[maxn];
int seg[N<<]; int siz[N]; ///当前节点保存的儿子数
int top[N]; ///当前节点所在链的顶端节点
int son[N]; ///保存重儿子
int dep[N]; ///当前节点深度
int fa[N]; ///当前节点的父亲
int id[N]; ///用来保存树中每个节点剖分后的新编号
int posi[N]; ///在线段树中的位置
int tid,pos; ///树链剖分
void dfs1(int u,int f,int deep){ ///找重边
dep[u]=deep;
fa[u]=f;
siz[u]=;
for(int i=head[u];~i;i=node[i].nxt){
int e=node[i].to;
if(e==f)continue;
dfs1(e,u,deep+);
siz[u]+=siz[e];
if(!son[u]||siz[son[u]]<siz[e])
son[u]=e;
}
}
void dfs2(int u,int tp){ ///连重边成重链
top[u]=tp;
id[u]=++tid;
posi[id[u]]=u;
if(!son[u])return;
dfs2(son[u],tp);
for(int i=head[u];~i;i=node[i].nxt){
int e=node[i].to;
if(e!=son[u]&&e!=fa[u])
dfs2(e,e);
}
} ///线段树
void build(int rt,int l,int r){
seg[rt]=-inf;
if(l==r) return;
int mid=l+r>>;
build(lson); build(rson);
seg[rt]=max(seg[rt<<],seg[rt<<|]);
} void add(int rt,int l,int r,int v){
if(l==r){
seg[rt]=v;
return;
}
int mid=l+r>>;
if(pos<=mid)add(lson,v);
else add(rson,v);
seg[rt]=max(seg[rt<<],seg[rt<<|]);
}
int query(int rt,int l,int r,int L,int R){
if(L<=l&&r<=R){return seg[rt];}
int mid=l+r>>;
int temp=INT_MIN;
if(L<=mid)temp=max(temp,query(lson,L,R));
if(R>mid) temp=max(temp,query(rson,L,R));
return temp;
} void ini(){
mst(head,-);hcnt=tid=;mst(seg,);
mst(son,);mst(siz,);
}
void add(int x,int y,int v){
node[hcnt].to=y,node[hcnt].nxt=head[x],node[hcnt].v=v,head[x]=hcnt++;
node[hcnt].to=x,node[hcnt].nxt=head[y],node[hcnt].v=v,head[y]=hcnt++;
}
int lca(int x,int y){
int ans=-inf;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans=max(ans,query(,,n,id[top[x]],id[x]));
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
if(x!=y)ans=max(ans,query(,,n,id[x]+,id[y]));
return ans;
}
int main(){
//freopen("in.txt","r",stdin);
int i,j,group,x,y,v,Case=;
group=read();
while(group--){
ini();
n=read();
for(i=;i<n;++i){
scanf("%d%d%d",&x,&y,&v);
edge[i].x=x,edge[i].y=y,edge[i].v=v;
add(x,y,v);
}
dfs1(,,);
dfs2(,);
build(,,n);
for(i=;i<n;i++){
if(dep[edge[i].x]<dep[edge[i].y])
swap(edge[i].x,edge[i].y);
pos=id[edge[i].x];
add(,,n,edge[i].v);
}
while(scanf("%s",str)!=EOF){
if(str[]=='D')break;
x=read();y=read();
if(str[]=='Q'){
printf("%d\n",lca(x,y));
}
else{
pos=id[edge[x].x];
add(,,n,y);
}
}
printf("\n");
}
return ;
}
SPOJ 375 QTREE的更多相关文章
- 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 375 Query on a tree(树链剖分)(QTREE)
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...
- SPOJ 375 树链剖分 QTREE - Query on a tree
人生第一道树链剖分的题目,其实树链剖分并不是特别难. 思想就是把树剖成一些轻链和重链,轻链比较少可以直接修改,重链比较长,用线段树去维护. 貌似大家都是从这篇博客上学的. #include <c ...
- SPOJ 375. Query on a tree (树链剖分)
Query on a tree Time Limit: 5000ms Memory Limit: 262144KB This problem will be judged on SPOJ. Ori ...
- SPOJ 375 树链剖分
SPOJ太慢了,SPOJ太慢了, 题意:给定n(n<=10000)个节点的树,每条边有边权,有两种操作:1.修改某条变的边权:2.查询u,v之间路径上的最大边权. 分析:树链剖分入门题,看这里: ...
- SPOJ 375. Query on a tree (动态树)
375. Query on a tree Problem code: QTREE You are given a tree (an acyclic undirected connected graph ...
- 动态树(Link Cut Tree) :SPOJ 375 Query on a tree
QTREE - Query on a tree #number-theory You are given a tree (an acyclic undirected connected graph) ...
- spoj 375 树链剖分 模板
QTREE - Query on a tree #tree You are given a tree (an acyclic undirected connected graph) with N no ...
随机推荐
- sql 百分比
select [city], bfb=cast(cast(count(*)*100./(select count(*) from [UserBasicInfo]) as decimal(10,0)) ...
- 摘:SQL Server数据类型的25种
我们大家都知道数据类弄是数据的一种基本属性,其主要是表示数据在实际操作中所表示信息的类型.任何一种计算机语言都定义了自己的数据类型. 当然,不同的程序语言都具有不同的特点,所定义的SQL Server ...
- 一名全栈工程师Node.js之路-转
Node.js 全球现状 虽然 Node.js 在国内没有盛行,但据 StackOverflow 2016 年开发者调查,其中 node.js .全栈.JavaScript 相关的技术在多个领域(包括 ...
- Node.js + Express + Ubuntu
1 . 怎么在ubuntu中,background的方式 启动express. 网站www /home/host/express/web/bin# nohup node www 2. Node.js的 ...
- ldap temp
#http://www.openldap.org/software/man.cgi?query=slapcat&apropos=0&sektion=0&manpath=Open ...
- python学习笔记(4)--聊天记录处理
说明: 1.把冒号和前面的名字去掉 2.男的台词放一个txt文件,女的台词放一个txt文件 3.遇到======就重新生成一个文件 record.txt: 婷婷:迪迪早啊! 迪迪:早啊! 婷婷:111 ...
- 基于html5和css3响应式全屏滚动页面切换效果
分享一款全屏响应式的HTML5和CSS3页面切换效果.这个页面布局效果对于那些页面要求固定100%高度和宽度的网站和APP来说是十分有用的.效果图如下: 在线预览 源码下载 HTML wrappe ...
- MapReduce编程实例5
前提准备: 1.hadoop安装运行正常.Hadoop安装配置请参考:Ubuntu下 Hadoop 1.2.1 配置安装 2.集成开发环境正常.集成开发环境配置请参考 :Ubuntu 搭建Hadoop ...
- udp program
UDP program UDP常用函数:recvfrom和sendto recvfrom ssize_t recvfrom(int sockfd, void *buf, size_t len, int ...
- 如意云路由刷PandoraBox
目录 1 准备固件 2 使用uboot刷机 2.1 修改IP 2.2 开始刷写 3 ssh登录 4 刷回如意云 准备固件 http://downloads.openwrt.org.cn/Pandora ...