发现链剖这东西好久不写想一遍写对是有难度的.. 果然是熟能生巧吧..

WC的dalao们都回来了 然后就用WC的毒瘤题荼毒了我们一波, 本来想打个T1 44分暴力 然后好像是特判写挂了还是怎么的就只能得28pts..

重新见到这些失踪的dalao灰常开心, 于是想让自己心情稍微差一点, 就想着把自己昨天写WA的QTREE重构一遍吧..

于是重构的sb链剖果然挂掉了... 出现了各种各样的漏洞... 忘记各种各样的句子, 然而退化成了暴力小数据也随便过看不出来啊~~~

但是还是在1h之内调对了_(:з」∠)_ 已经很满意了... 不过交的时候把自己的样例交上去还CE了一次orz...

就这样吧..

题目分析: 两种操作:

  1. 修改第\(i\)条边(输入顺序).
  2. 查询两个点\(u,v\)路径上边权的最大值.

链剖的话边权不是很好搞, 考虑采用之前学过的一种做法

连x->y边的时候可以拆成x->z->y的两条边啊,然后把边权放在z就可以了

这样处理完就变成了裸的单点改区间查, 随便套个线段树水一下就好了(说得轻巧, 你细节死成什么样自己心里没点数么= =

代码:

#include <cstdio>
#include <cstring>
const int N=202020;
inline int gn(int a=0,char c=0,int f=1){
for(;(c<'0'||c>'9')&&c!='-';c=getchar());
if(c=='-') f=-1,c=getchar();
for(;c>='0'&&c<='9';c=getchar()) a=a*10+c-'0'; return a*f;
}
inline int max(const int& a,const int& b){
return a>b?a:b;
}
struct edge{
int to,next;
}e[N]; int v[N],tot;
void buildedge(int x,int y){
e[++tot].to=y; e[tot].next=v[x]; v[x]=tot;
e[++tot].to=x; e[tot].next=v[y]; v[y]=tot;
}
int fa[N],ez[N],d[N],sz[N];
void dfs1(int x){ ez[x]=x; sz[x]=1;
for(int i=v[x];i;i=e[i].next){
int y=e[i].to;
if(fa[x]!=y){
fa[y]=x; d[y]=d[x]+1; dfs1(y); sz[x]+=sz[y];
if(ez[x]==x||sz[y]>sz[ez[x]]) ez[x]=y;
}
}
}
int pos[N],rank[N],tp[N],a[N>>1],ti;
void dfs2(int x,int tpx){
tp[x]=tpx; pos[++ti]=x; rank[x]=ti;
if(ez[x]!=x) dfs2(ez[x],tpx);
for(int i=v[x];i;i=e[i].next){
int y=e[i].to;
if(y!=fa[x]&&y!=ez[x]) dfs2(y,y);
}
}
int t[N<<2],n;
inline void update(int x){
t[x]=max(t[x<<1],t[x<<1|1]);
}
void build(int x,int l,int r){
if(l==r){
t[x]=a[pos[++ti]];
return;
} int mid=(l+r)>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
update(x);
}
void change(int x,int l,int r,int k,int s){
if(l==r){
t[x]=s; return;
} int mid=(l+r)>>1;
if(k<=mid) change(x<<1,l,mid,k,s);
else change(x<<1|1,mid+1,r,k,s);
update(x);
}
int query(int x,int l,int r,int L,int R){
if(L<=l&&r<=R) return t[x];
int mid=(l+r)>>1,ans=-0x7fffffff;
if(L<=mid) ans=max(ans,query(x<<1,l,mid,L,R));
if(R>mid) ans=max(ans,query(x<<1|1,mid+1,r,L,R));
return ans;
} inline int querya(int x,int y){ int ans=-0x7fffffff;
while(tp[x]!=tp[y])
if(d[tp[x]]>d[tp[y]]) ans=max(ans,query(1,1,n,rank[tp[x]],rank[x])),x=fa[tp[x]];
else ans=max(ans,query(1,1,n,rank[tp[y]],rank[y])),y=fa[tp[y]];
if(d[x]<d[y]) ans=max(ans,query(1,1,n,rank[x],rank[y]));
else ans=max(ans,query(1,1,n,rank[y],rank[x]));
return ans;
} inline void init(){
memset(a,192,sizeof(a));
memset(v,0,sizeof(v));
ti=tot=0;
}
inline void work(){ init();
n=gn(); int nn=n; n=n*2-1;
for(int i=1;i<nn;++i){
int x=gn(),y=gn(),z=gn(); a[nn+i]=z;
buildedge(x,nn+i); buildedge(nn+i,y);
}
dfs1(1); dfs2(1,1); fa[1]=1;
ti=0; build(1,1,n);
char c[10];
while(1){
scanf("%s",c); if(c[0]=='D') break;
int x=gn(),y=gn();
if(c[0]=='Q') printf("%d\n",querya(x,y));
else change(1,1,n,rank[nn+x],y);
}
}
int main(){
int T=gn();
while(T--)work();
}

【学术篇】SPOJ QTREE 树链剖分的更多相关文章

  1. SPOJ QTREE 树链剖分

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

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

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

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

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

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

  5. SPOJ 375 树链剖分

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

  6. SPOJ 375 (树链剖分 - 边权剖分 - 修改单边权)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28982#problem/I 给你一棵有边权的树,有两个操作:一个操作是输出l到 ...

  7. SPOJ 375 (树链剖分+线段树)

    题意:一棵包含N 个结点的树,每条边都有一个权值,要求模拟两种操作:(1)改变某条边的权值,(2)询问U,V 之间的路径中权值最大的边. 思路:最近比赛总是看到有树链剖分的题目,就看了论文,做了这题, ...

  8. SPOJ375.QTREE树链剖分

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

  9. spoj 375 树链剖分 模板

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

随机推荐

  1. 36-Ubuntu-用户管理-01-新建用户useradd

    创建用户/设置密码/删除用户/确认用户信息 序号 命令 作用 说明 01 sudo useradd -m -g 组名 新建用户名 添加新用户 -m 自动建立用户家目录 -g 指定用户所在的组,否则会建 ...

  2. mac 常使用的一些小技巧

    全选 command +A 剪切 command + x 复制 ommand + c 粘贴 command + v 撤销 command + z 聚焦搜索 command + 空格 退出全屏窗口 Co ...

  3. react 中刷新,路由传参数丢失不存在了?

    你可能在Link to没写state {{pathname:'/report',state:{storageClear:this.state.storageClear}}}

  4. Install .NET Core Runtime on Linux Ubuntu 16.04 x64

    原文链接https://www.microsoft.com/net/download/linux-package-manager/ubuntu16-04/runtime-current nstall ...

  5. Linux初学习之 rm 命令

    现在我们来仔细的学习一下linux的rm命令,这个命令顾名思义(我猜的,嘻嘻,是remove) 命令格式: rm [OPTION]... FILE... Remove (unlink) the FIL ...

  6. asp.net MVC项目,localhost响应时间过长

    1.早上高高兴兴的吃完早餐,敲了几句代码,准备调试,竟然发现VS调试项目打开的很慢,最后报错如下图 2.那就很可能是IIS问题嘛,IIS重启了一下,还是不行,在地址栏输入localhost,如下图(本 ...

  7. PushSharp 由于远程方已关闭传输流,身份验证失败。

    前段时间用到了PushSharp给APNS发推送,但是用的时候遇见很诡异的事情,每次第一次运行的时候能成功发送到 但是接下来就无限的提示“由于远程方已关闭传输流,身份验证失败. “ 然后我就各种找原因 ...

  8. Echart中X轴数据过多时横向拉动展示

    chart.setOption( { tooltip: { trigger: 'axis' }, toolbox: { feature: { saveAsImage: {} } }, grid: { ...

  9. react 使用react-router-dom 在Route对象上component 参数接收的是一个方法而非一个对象

    其实对于jsx语法 一直觉的它有点清晰都不是很好,js和html混在一起有点不伦不类的样子,以下是我在使用react中遇到的一个很奇葩的事情 假定你定义了一个component Mine import ...

  10. MapReduce分区数据倾斜

    什么是数据倾斜? 数据不可避免的出现离群值,并导致数据倾斜,数据倾斜会显著的拖慢MR的执行速度 常见数据倾斜有以下几类 1.数据频率倾斜   某一个区域的数据量要远远大于其他区域 2.数据大小倾斜  ...