【SPOJ-QTREE】树链剖分
树链剖分学习
https://blog.csdn.net/u013368721/article/details/39734871
https://www.cnblogs.com/George1994/p/7821357.html
核心:节点u的轻儿子为v 轻儿子的性质:size[v] <= size[u] / 2
故:每走一条轻链,节点数减少一半
又因:两个节点之间的路径,必为重链和轻边交替
故:从根结点到树上任意点经过的轻边以及重链都不会超过logn条
http://acm.hust.edu.cn/vjudge/problem/13013
树链剖分模版题
题意:
有一棵N个节点的树(1<=N<=10000),N-1条边,边的编号为1~N-1,每条边有一个权值,要求模拟两种操作:
1:QUERY x y 求节点x和节点y之间的路径中权值最大的边。
2:CHANGE p k修改第p条边的权值为k。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 8 const int N=10010; 9 char s[10]; 10 struct trnode{ 11 int lc,rc,l,r,c; 12 }t[2*N]; 13 struct node{ 14 int x,y,d,next; 15 }a[2*N],b[N]; 16 int n,tl,z,len; 17 int first[N],tot[N],son[N],fa[N],dep[N],ys[N],top[N]; 18 19 int maxx(int x,int y){return x>y ? x:y;} 20 21 void ins(int x,int y,int d) 22 { 23 len++; 24 a[len].x=x;a[len].y=y;a[len].d=d; 25 a[len].next=first[x];first[x]=len; 26 } 27 28 int build_tree(int l,int r) 29 { 30 int x=++tl; 31 t[x].l=l;t[x].r=r;t[x].c=0; 32 t[x].lc=t[x].rc=-1; 33 if(l<r) 34 { 35 int mid=(l+r)>>1; 36 t[x].lc=build_tree(l,mid); 37 t[x].rc=build_tree(mid+1,r); 38 } 39 return x; 40 } 41 42 void change(int x,int p,int c) 43 { 44 if(t[x].l==t[x].r) {t[x].c=c;return;} 45 int lc=t[x].lc,rc=t[x].rc,mid=(t[x].l+t[x].r)>>1; 46 if(p<=mid) change(lc,p,c); 47 else change(rc,p,c); 48 t[x].c=maxx(t[lc].c,t[rc].c); 49 } 50 51 int query(int x,int l,int r) 52 { 53 if(t[x].l==l && t[x].r==r) return t[x].c; 54 int lc=t[x].lc,rc=t[x].rc,mid=(t[x].l+t[x].r)>>1; 55 if(r<=mid) return query(lc,l,r); 56 else if(l>mid) return query(rc,l,r); 57 return maxx(query(lc,l,mid),query(rc,mid+1,r)); 58 } 59 60 void dfs1(int x) 61 { 62 tot[x]=1;son[x]=0; 63 for(int i=first[x];i;i=a[i].next) 64 { 65 int y=a[i].y; 66 if(y==fa[x]) continue; 67 fa[y]=x; 68 dep[y]=dep[x]+1; 69 dfs1(y); 70 if(tot[son[x]]<tot[y]) son[x]=y; 71 tot[x]+=tot[y]; 72 } 73 } 74 75 void dfs2(int x,int tp) 76 { 77 ys[x]=++z;top[x]=tp; 78 if(son[x]) dfs2(son[x],tp); 79 for(int i=first[x];i;i=a[i].next) 80 { 81 int y=a[i].y; 82 if(y==fa[x] || y==son[x]) continue; 83 dfs2(y,y); 84 } 85 } 86 87 int solve(int x,int y) 88 { 89 int tx=top[x],ty=top[y],ans=0; 90 while(tx!=ty) 91 { 92 if(dep[tx]>dep[ty]) swap(tx,ty),swap(x,y);//debug swap(x,y)之前漏了 93 ans=maxx(ans,query(1,ys[ty],ys[y])); 94 y=fa[ty];ty=top[y]; 95 } 96 if(x==y) return ans; 97 else 98 { 99 if(dep[x]>dep[y]) swap(x,y); 100 return maxx(ans,query(1,ys[son[x]],ys[y])); 101 } 102 } 103 104 int main() 105 { 106 freopen("a.in","r",stdin); 107 // freopen("a.out","w",stdout); 108 int T; 109 scanf("%d",&T); 110 while(T--) 111 { 112 scanf("%d",&n); 113 len=0;tl=0;z=0;dep[1]=0;tot[0]=0; 114 memset(fa,0,sizeof(fa)); 115 memset(first,0,sizeof(first)); 116 for(int i=1;i<n;i++) 117 { 118 scanf("%d%d%d",&b[i].x,&b[i].y,&b[i].d); 119 ins(b[i].x,b[i].y,b[i].d); 120 ins(b[i].y,b[i].x,b[i].d); 121 } 122 dfs1(1); 123 dfs2(1,1); 124 build_tree(1,z); 125 for(int i=1;i<n;i++) if(dep[b[i].x]>dep[b[i].y]) swap(b[i].x,b[i].y); 126 for(int i=1;i<n;i++) change(1,ys[b[i].y],b[i].d); 127 while(1) 128 { 129 scanf("%s",s); 130 int x,y,d; 131 if(s[0]=='Q') 132 { 133 scanf("%d%d",&x,&y); 134 printf("%d\n",solve(x,y)); 135 } 136 if(s[0]=='C') 137 { 138 scanf("%d%d",&x,&d); 139 change(1,ys[b[x].y],d); 140 } 141 if(s[0]=='D') break; 142 } 143 } 144 return 0; 145 }
转载于:https://www.cnblogs.com/KonjakJuruo/p/5746080.html
【SPOJ-QTREE】树链剖分相关推荐
- 【高级数据结构】[SPOJ QTREE]树链剖分/动态树各一模板
题目: 树链剖分: #include<cstdio> #include<cstring> #include<algorithm> using namespace s ...
- SPOJ 375 树链剖分学习
学习树链剖分的第一题,第二个dfs忘记递归了(太蠢),re了两发,改过来以后就1A了. 学习树链剖分可以参考这篇博客:http://blog.sina.com.cn/s/blog_7a17468201 ...
- SPOJ QTree【树链剖分】
一 题目 QTREE 二 分析 第一道树链剖分的题,写的好艰难啊. 题意还是比较好理解的,就是在树上操作. 对于修改,题中要求的是单点修改,就算是直接树上操作也是非常简单的. 对于查询,查询的时候,是 ...
- SPOJ - QTREE Query on a tree(树链剖分+线段树)
题目链接:点击查看 题目大意:给出一棵由n个点组成的树,再给出数个操作,每次操作分为下列几种类型: QUERY x y:询问点x-点y这条路径上的所有边权的最大值 CHANGE x y:将第x条边的权 ...
- SPOJ 375. Query on a tree (树链剖分)
题目链接: http://www.spoj.com/problems/QTREE/ 375. Query on a tree Problem code: QTREE You are given a t ...
- spoj 375 Query on a tree (树链剖分)
题目链接: http://www.spoj.com/problems/QTREE/ 题意: 给一颗树,每条边有一个权值.有两种操作: 1.修改某条边的值: 2.询问a.b两点路径上边权的最大值. 分析 ...
- SPOJ - QTREE3Query on a tree again!——树链剖分
[题目描述] SPOJ - QTREE3Query on a tree again! [题目分析] 题目要求是输出从111到xxx的路径上遇到的第一个黑色的点.我们可以用树链剖分(不了解的同学请出门左 ...
- [SPOJ375]QTREE - Query on a tree【树链剖分】
题目描述 给你一棵树,两种操作. 修改边权,查找边权的最大值. 分析 我们都知道,树链剖分能够维护点权. 而且每一条边只有一个,且唯一对应一个儿子节点,那么就把信息放到这个儿子节点上. 注意,lca的 ...
- SPOJ 375 query on a tree 树链剖分
题意: 给一棵树型数据结构 ①支持修改边的权值 ②支持成段边权最值查询 树链剖分入门题. 树链剖分+线段树 用的notonlysuccess的线段树--不开结构体事先预处理的那种 我以前写的 ...
- 树链剖分入门——[kuangbin]树链剖分
树链剖分的本质就是将一棵树拆分成一段一段连续的区间,然后放在一起就可以用一棵单独的线段树处理区间问题,只需要将树上节点和线段树节点的对应关系求好就可以很方便的互相转换,而树上两点之间路径的相关问题就可 ...
最新文章
- Unicode转义(\uXXXX)的编码和解码
- docker应用到生产环境的前提
- 计算机专业英语 侯进,06年的录取名单,谁知道麻烦发到这里,谢谢啦!!!
- 天猫、京东双十一总交易额7697亿元;苹果测试可折叠iPhone显示屏,或将于2022年问世;.NET 5.0发布|极客头条
- JavaScript初阶(十)---------- 数组
- qcom charger
- DLL注入——使用全局钩子
- Redis基本类型之Set类型
- 微信QQ支付宝三合一收款二维码实现原理
- 手机IP和内网外网IP的访问
- 来篇鸡汤文吧,教你如何七周内从小菜鸟成长为一名合格的数据分析师
- 软碟通系统U盘制作教程
- Springboot-Vue项目框架每部分的介绍
- ipadpencil长时间未用,插入iPad中没反应的解决方法
- 腾讯CSIG-腾讯云-后台开发-面经(已拿offer)
- python字符串的特点_字符串特点_清华尹成python入门教程_少儿编程视频-51CTO学院...
- uni-app App端半屏连续扫码
- kali linux中goldendict查词慢的问题
- Java实现批量重命名文件
- 自定义相机Camera,相机/视频实时滤镜 - android