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 ...
随机推荐
- EMQ ---v2.3.11源码成熟度
从原作者那边了解到,总体还可以,但是做不到99.99%稳定.主要是连接内存占用没有保护. pubsub均衡时很稳定,但是集群或大量消息向少量订阅发布时会崩溃,小概率情况. EMQ中CPU是公平分配给M ...
- /usr/lib64改名字风波
注:本文描述请勿模仿,仅限万一遇到这种情况一试. 一不小心做了一个操作: cd /usr mv lib64 lib64-bak 然后奇异的发现: cp不能用了!ls也不能用了…… 提示信息如下: -b ...
- windows下MongoDB的安装,配置与开机自启动
关于简介不多说百度去吧少年.. MongoDB详细安装: 1.进入官网,点击DOWNLOAD MONGODB,下载所需要的版本.. 我这里把下载的文件放在d\MongoDB文件夹下,点击下载的官方镜像 ...
- ubuntu下禁用和恢复触摸板
1.一般禁用选项在 settings > mouse and touchpad 中.(16.04通过实验)如果无法禁用或者希望恢复,向下看. 2.命令行键入: xinput ,插卡touchpa ...
- 如何隐藏你的 Linux 的命令行历史
如果你是 Linux 命令行的用户,有的时候你可能不希望某些命令记录在你的命令行历史中.原因可能很多,例如,你在公司担任某个职位,你有一些不希望被其它人滥用的特权.亦或者有些特别重要的命令,你不希望在 ...
- cookie,session,localStage,sessionStage区别
Cookie和Session详解 1.什么是Cookie Cookie是存放在客户端浏览器的Name/Value键值对,访问服务器时,会自动传递给服务器. Cookie的生成方式有两种,服务器写入,客 ...
- win7下如何显示缅文和使用缅文输入法?
windows 7 操作系统默认不支持缅文,所以缅文在win7上不能显示,当然也没有提供缅文输入法. 一.显示缅文 windows系统下显示缅文字母只需要安装缅文字体就可以了.目前常见的缅文字体就是Z ...
- git学习(一):git的版本库在哪儿
查看版本 git --version # 查看git的版本 设置或者查看用户名和邮箱 git config --global user.name "tuhooo" // 如果后面没 ...
- Netty系列之Netty百万级推送服务设计要点(转)
1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...
- 概率dp - UVA 11021 Tribles
Tribles Problem's Link: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=33059 Mean: 有k个细 ...