SPOJ 375 QTREE - Query on a tree
思路
注意本题只能用C,不能用C++
其他的都和上一题一样
代码
#include <stdio.h>
#include <string.h>
#define MAXN 10010
int dfs_clock,dep[MAXN*2],heason[MAXN*2],id[MAXN*2],sz[MAXN*2],top[MAXN*2],fa[MAXN*2],w_p[MAXN*2],v[MAXN*2],fir[MAXN*2],nxt[MAXN*2],w[MAXN*2],val[MAXN*2],maxx[MAXN*5],cnt;
struct Edge{
int u,v,w;
}E[MAXN*2];
int max(int a,int b){
return (a>b)?a:b;
}
void addedge(int ui,int vi,int wi){
++cnt;
v[cnt]=vi;
w[cnt]=wi;
nxt[cnt]=fir[ui];
fir[ui]=cnt;
}
void dfs1(int u,int f,int wx){
fa[u]=f;
sz[u]=1;
w_p[u]=wx;
for(int i=fir[u];i;i=nxt[i]){
if(v[i]==f)
continue;
dep[v[i]]=dep[u]+1;
dfs1(v[i],u,w[i]);
sz[u]+=sz[v[i]];
if(heason[u]==0||sz[v[i]]>sz[heason[u]])
heason[u]=v[i];
}
}
void dfs2(int u,int f,int topf){
id[u]=++dfs_clock;
val[id[u]]=w_p[u];
top[u]=topf;
if(!heason[u])
return;
dfs2(heason[u],u,topf);
for(int i=fir[u];i;i=nxt[i]){
if(v[i]==f||v[i]==heason[u])
continue;
dfs2(v[i],u,v[i]);
}
}
void pushup(int o){
maxx[o]=max(maxx[o<<1],maxx[o<<1|1]);
}
void build(int l,int r,int o){
if(l==r){
maxx[o]=val[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,o<<1);
build(mid+1,r,o<<1|1);
pushup(o);
}
void update1(int l,int r,int pos,int o,int c){
if(l==r){
maxx[o]=c;
return;
}
int mid=(l+r)>>1;
if(pos<=mid)
update1(l,mid,pos,o<<1,c);
else
update1(mid+1,r,pos,o<<1|1,c);
pushup(o);
}
void update(int o,int c){
update1(1,dfs_clock,id[o],1,c);
}
int query1(int L,int R,int l,int r,int o){
if(L<=l&&r<=R)
return maxx[o];
int mid=(l+r)>>1,ans=0;
if(L<=mid)
ans=max(ans,query1(L,R,l,mid,o<<1));
if(R>mid)
ans=max(ans,query1(L,R,mid+1,r,o<<1|1));
return ans;
}
int query(int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
int t=x;
x=y;
y=t;
}
ans=max(ans,query1(id[top[x]],id[x],1,dfs_clock,1));
x=fa[top[x]];
}
if(dep[x]>dep[y]){
int t=x;
x=y;
y=t;
}
ans=max(ans,query1(id[x],id[y],1,dfs_clock,1));
return ans;
}
int lca(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
int t=x;
x=y;
y=t;
}
x=fa[top[x]];
}
return (dep[x]<dep[y])?x:y;
}
void init(void){
dfs_clock=0;
memset(dep,0,sizeof(dep));
memset(heason,0,sizeof(heason));
memset(id,0,sizeof(id));
memset(sz,0,sizeof(sz));
memset(top,0,sizeof(top));
memset(fa,0,sizeof(fa));
memset(w_p,0,sizeof(w_p));
memset(v,0,sizeof(v));
memset(fir,0,sizeof(fir));
memset(nxt,0,sizeof(nxt));
memset(w,0,sizeof(w));
memset(val,0,sizeof(val));
memset(maxx,0,sizeof(maxx));
cnt=0;
memset(E,0,sizeof(E));
}
int n,T;
int main(){
scanf("%d",&T);
while(T--){
init();
scanf("%d",&n);
for(int i=1;i<n;i++){
scanf("%d %d %d",&E[i].u,&E[i].v,&E[i].w);
addedge(E[i].u,E[i].v,E[i].w);
addedge(E[i].v,E[i].u,E[i].w);
}
dfs1(1,0,0);
dfs2(1,0,1);
build(1,dfs_clock,1);
char opt[10];
while(1){
scanf("%s",&opt);
if(opt[0]=='D')
break;
if(opt[0]=='Q'){
int a,b;
scanf("%d %d",&a,&b);
int LCA=lca(a,b);
// printf("lca=%d\n",LCA);
int t=w_p[LCA];
update(LCA,0);
int ans=query(a,b);
update(LCA,t);
printf("%d\n",ans);
}
else{
int a,b;
scanf("%d %d",&a,&b);
int t=(dep[E[a].u]>dep[E[a].v])?E[a].u:E[a].v;
w_p[t]=b;
update(t,b);
}
}
}
return 0;
}
SPOJ 375 QTREE - Query on a tree的更多相关文章
- spoj 375 QTREE - Query on a tree 树链剖分
题目链接 给一棵树, 每条边有权值, 两种操作, 一种是将一条边的权值改变, 一种是询问u到v路径上最大的边的权值. 树链剖分模板. #include <iostream> #includ ...
- SPOJ VJudge QTREE - Query on a tree
Query on a tree Time Limit: 851MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Submi ...
- 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 ...
- QTREE - Query on a tree
QTREE - Query on a tree 题目链接:http://www.spoj.com/problems/QTREE/ 参考博客:http://blog.sina.com.cn/s/blog ...
- SP375 QTREE - Query on a tree (树剖)
题目 SP375 QTREE - Query on a tree 解析 也就是个蓝题,因为比较长 树剖裸题(基本上),单点修改,链上查询. 顺便来说一下链上操作时如何将边上的操作转化为点上的操作: 可 ...
- SPOJ 375 树链剖分 QTREE - Query on a tree
人生第一道树链剖分的题目,其实树链剖分并不是特别难. 思想就是把树剖成一些轻链和重链,轻链比较少可以直接修改,重链比较长,用线段树去维护. 貌似大家都是从这篇博客上学的. #include <c ...
- spoj QTREE - Query on a tree(树链剖分+线段树单点更新,区间查询)
传送门:Problem QTREE https://www.cnblogs.com/violet-acmer/p/9711441.html 题解: 树链剖分的模板题,看代码比看文字解析理解来的快~~~ ...
- SPOJ QTREE Query on a tree --树链剖分
题意:给一棵树,每次更新某条边或者查询u->v路径上的边权最大值. 解法:做过上一题,这题就没太大问题了,以终点的标号作为边的标号,因为dfs只能给点分配位置,而一棵树每条树边的终点只有一个. ...
- SPOJ QTREE Query on a tree VI
You are given a tree (an acyclic undirected connected graph) with n nodes. The tree nodes are number ...
随机推荐
- 博客搬家 https://hanwang945.github.io/
博客搬家 https://hanwang945.github.io/
- gdb常用的指令
推荐一篇详细的gdb文章:http://witmax.cn/gdb-usage.html 1. 常用的gdb 命令 编译程序时需要加上-g,之后才能用gdb进行调试:gcc -g main.c -o ...
- Android系统裁剪:手把手教你如何进行系统裁剪
前言:android系统裁剪优化一直是各个厂商定制产品的关键步骤,包括浅层次的去除不必要的apk(android apk裁剪定制 )和深层次的裁剪整个编译系统和框架层. android作为开源系统 ...
- opencart3图片Google Merchant Center验证通过不了的解决方法
最近在做一个opencart项目,有对接Google Merchant Center,但是一直提示产品图片验证无法通过,ytkah看了一下图片路径,/image/cache/catalog/demo/ ...
- CDI services--Scope(生命周期)&&EL.(Sp El)
一.EL/SpEL 1.EL语言(CDI与表达式语言(EL)集成,允许在JavaServer Faces页面或JavaServer Pages页面中直接使用任何组件) 1)概述:EL是JSP内置的表达 ...
- C++ 自定义订单号
自定义订单号 #include<iostream> #include<stack> #include <time.h> #include <sys/timeb ...
- svn 安装
SVN简介: 为什么要使用SVN? 程序员在编写程序的过程中,每个程序员都会生成很多不同的版本,这就需要程序员有效的管理代码,在需要的时候可以迅速,准确取出相应的版本. Subversion是什么? ...
- BigDecimal源码
1 public BigDecimal(char[] in, int offset, int len, MathContext mc) {// 使用字符数组的构造方法,一般我们推荐使用的是一Strin ...
- ABP 2.0.2 升到 2.2.1
1.选择解决方案 右键 管理 nuget 更新 输入abp 这里只升级 abp的包 点升级 2.update-database 可能需要你添加个迁移(这一步可能不需要) 3.Core 项目下面的Au ...
- maven clean或package报错
[ERROR] Failed to execute goal on project jeesns-service: Could not resolve dependencies for project ...