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

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. PAT_A1139#First Contact

    Source: PAT A1139 First Contact (30 分) Description: Unlike in nowadays, the way that boys and girls ...

  2. Jackson第一个程序

    再进入学习jackson库的细节之前,让我们来看看应用程序操作功能.在这个例子中,我们创建一个Student类.将创建一个JSON字符串学生的详细信息,并将其反序列化到学生的对象,然后将其序列化到JS ...

  3. EM相关两个算法 k-mean算法和混合高斯模型

    转自http://www.cnblogs.com/jerrylead/archive/2011/04/06/2006924.html http://www.cnblogs.com/jerrylead/ ...

  4. mongo之$max

    原集合: { _id: 1, highScore: 800, lowScore: 200 } 应用: #意思是:更新_id 等于1 的记录,条件是highScore 950>原纪录的highSc ...

  5. http://localhost:8080 is requesting your username and password

    after you startup your tomcat,  you type a concrete request url  in broswer, the tomcat probably wil ...

  6. Arrays 001

    1.1 Array Initalization First of all, we need know Java arrays is static. When the array is initiali ...

  7. Python Faker的使用 及 常用函数的查询

    安装faker  pip install faker faker的使用 引用:from faker import Faker 初始化:f=Faker(locale='zh_CN') # 默认是en_U ...

  8. Linux 错误: $'\r': command not found

    是linux无法解析$'\r'.这其实是windows与linux系统的差异导致的. 因为linux上的换行符为\n,而windows上的换行符为\r\n.所以脚本到linux上就无法解析了. 通常的 ...

  9. 传输文件到docker容器

    传输文件到docker容器 首先需要知道docker容器的container_id,可以使用docker ps命令来查看你要操作的docker容器的container_id Docker容器向宿主机传 ...

  10. redis安装到本地服务的方法

    要安装Redis,首先要获取安装包. Windows的Redis安装包需要到以下GitHub链接找到. 链接:https://github.com/MSOpenTech/redis 打开网站后,找到R ...