题目链接:传送门

题目大意:给一棵无根树,树边有权值,有很多次操作,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的更多相关文章

  1. spoj 375 QTREE - Query on a tree 树链剖分

    题目链接 给一棵树, 每条边有权值, 两种操作, 一种是将一条边的权值改变, 一种是询问u到v路径上最大的边的权值. 树链剖分模板. #include <iostream> #includ ...

  2. SPOJ 375 QTREE - Query on a tree

    思路 注意本题只能用C,不能用C++ 其他的都和上一题一样 代码 #include <stdio.h> #include <string.h> #define MAXN 100 ...

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

  4. SPOJ 375 树链剖分 QTREE - Query on a tree

    人生第一道树链剖分的题目,其实树链剖分并不是特别难. 思想就是把树剖成一些轻链和重链,轻链比较少可以直接修改,重链比较长,用线段树去维护. 貌似大家都是从这篇博客上学的. #include <c ...

  5. SPOJ 375. Query on a tree (树链剖分)

    Query on a tree Time Limit: 5000ms Memory Limit: 262144KB   This problem will be judged on SPOJ. Ori ...

  6. SPOJ 375 树链剖分

    SPOJ太慢了,SPOJ太慢了, 题意:给定n(n<=10000)个节点的树,每条边有边权,有两种操作:1.修改某条变的边权:2.查询u,v之间路径上的最大边权. 分析:树链剖分入门题,看这里: ...

  7. SPOJ 375. Query on a tree (动态树)

    375. Query on a tree Problem code: QTREE You are given a tree (an acyclic undirected connected graph ...

  8. 动态树(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) ...

  9. spoj 375 树链剖分 模板

    QTREE - Query on a tree #tree You are given a tree (an acyclic undirected connected graph) with N no ...

随机推荐

  1. ASP.NET Identity & OWIN 学习资料

    有关 ASP.NET Identity 的更多细节: http://www.asp.net/identity 从一个空项目中添加 ASP.NET Identity 和 OWIN 支持: http:// ...

  2. Mysql5.7的初始密码更改

    软件版本的变化真是让人兴奋…… Linux服务器决定安装使用mysql 5.7了. 愉快的去官网下载安装包:https://dev.mysql.com/downloads/mysql/ 解决完所有依赖 ...

  3. 文本检测: CTPN

    参考: https://zhuanlan.zhihu.com/p/37363942 https://zhuanlan.zhihu.com/p/34757009 https://zhuanlan.zhi ...

  4. Cocos2d-x3.0游戏实例之《别救我》第六篇——从代码中获取UI控件

    这篇的内容非常easy,获取UI控件,然后使用它. 还记得我们在UI编辑器中给三个button分别命名了吧? 如今要用上了. 笨木头花心贡献,啥?花心?不呢,是用心~ 转载请注明,原文地址: http ...

  5. HDU 1016:Prime Ring Problem

    Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  6. 【Tips】【UE】总结自己常用的UltraEdit使用技巧

    如果您问我每天都要打开的软件是什么,那毫无疑问是UltraEdit!作为一位DBA,每天都要写各种脚本,尤其是在对具有超多行行的大文件进行精心编辑时,没有一个好的文本编辑器是不成的.掐指一算,哇塞,自 ...

  7. NGINX + LUA实现复杂的控制

    安装lua_nginx_module 模块 lua_nginx_module 可以一步步的安装,也可以直接用淘宝的OpenResty Centos和debian的安装就简单了.. 这里说下freebs ...

  8. http_load使用详解

    1.什么是http_loadhttp_load是一款基于Linux平台的web服务器性能测试工具,用于测试web服务器的吞吐量与负载,web页面的性能. 2.http_load的安装1)下载地址wge ...

  9. vue-cli中实现全选、单选计算总价格(vue2.0)

    <template> <div> <table> <tr> <td><input type="checkbox" ...

  10. Java Mail(二):JavaMail介绍及发送一封简单邮件

    http://blog.csdn.net/ghsau/article/details/17839983 ************************************************ ...