QTREE----树剖
题目内容:
————————————————————————————————————————————————————
| Time Limit: 851MS | Memory Limit: 1572864KB | 64bit IO Format: %lld & %llu |
Description
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1.
We will ask you to perfrom some instructions of the following form:
- CHANGE i ti : change the cost of the i-th edge to ti
or - QUERY a b : ask for the maximum edge cost on the path from node a to node b
Input
The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.
For each test case:
- In the first line there is an integer N (N <= 10000),
- In the next N-1 lines, the i-th line describes the i-th edge: a line with three integers a b c denotes an edge between a, b of cost c (c <= 1000000),
- The next lines contain instructions "CHANGE i ti" or "QUERY a b",
- The end of each test case is signified by the string "DONE".
There is one blank line between successive tests.
Output
For each "QUERY" operation, write one integer representing its result.
Example
Input:
1 3
1 2 1
2 3 2
QUERY 1 2
CHANGE 1 3
QUERY 1 2
DONE Output:
1
3
——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
第一次写树剖,好长时间写的代码,可是卡了,又过了好长时间才调,又调了好长时间才过。昨天刚刚调试成功。笨啊!!!!!!!!!!!!
树链剖分:就是把树剖成链。
1、剖的依据为子树的大小。最大的为重儿子,其它的为轻儿子。连接重儿子的边为重边,其它的为轻边。重边组成重链。
2、把重链依次放入线段树中,进行维护。
编程过程:
1、读入图(边表)。
2、第一次DFS,维护树中各个点的深度、父亲、子树大小、重儿子。
3、第二次DFS,维护树中各个链的顶节点,和各个节点在线段树中的位置。
4、建空线段树。
5、依次读取各条边(因为边表每边读取2边,所以要隔一条读一条),调整U,V的次序,保证边权落在子节点上,更新子节点在线段树中的位置。
6、读取到更新命令时,依照(5)中的方法更新,但是因为U、V的次序已经调整,则无需调整,只需要更新边2*x-1的子节点即可。
7、读取到查询命令时,首先判断两点是否在一条链上,(a)如果不,查询深度更深的点到它所在链的链顶的最大值,然后让该点更新为链顶点的父亲,并更新链顶继续判断,直到在一条链上为止。(b)如果在一条链上则,2点是否为同一点,如果是则直接返回,否则调整U、v两点的位置,查询u在线段树中位置+1(因为U点代表U上边的边)到v的位置的最大值,更新ans,返回输出。
1 #include<cstdio>
2 #include<iostream>
3 #include<cstring>
4
5 using namespace std;
6 struct edge
7 {
8 int u,v,w,next;
9 }e[20010];
10 struct node
11 {
12 int l,r,val;
13 node * lc,* rc;
14 }*root=NULL;
15 int t,n;
16 int head[10010],js,p;
17 int fa[10010],son[10010],dep[10010],top[10010],siz[10010],fpos[10010],pos[10010];
18 void init()
19 {
20 js=0;
21 memset(head,0,sizeof(head));
22 p=0;
23 memset(e,0,sizeof(e));
24 memset(son,0,sizeof(son));
25 }
26 void addage(int u,int v,int w)
27 {
28 e[++js].u=u;e[js].v=v;e[js].w=w;
29 e[js].next=head[u];head[u]=js;
30 }
31 void dfs(int u,int f,int d)//?????????????????
32 {
33 fa[u]=f;dep[u]=d;siz[u]=1;
34 for(int i=head[u];i;i=e[i].next)
35 {
36 int v=e[i].v;
37 if(v!=f)
38 {
39 dfs(v,u,d+1);
40 siz[u]+=siz[v];
41 if(!son[u]||siz[son[u]]<siz[v])
42 son[u]=v;
43 }
44 }
45 }
46 void getpos(int u,int tp)//??top,pos(????????)
47 {
48 top[u]=tp;
49 pos[u]=++p;
50 // fpos[pos[u]]=u;
51 if(!son[u])return;
52 getpos(son[u],tp);
53 for(int i=head[u];i;i=e[i].next)
54 {
55 int v=e[i].v;
56 if(v!=son[u]&&v!=fa[u])
57 getpos(v,v);
58 }
59 }
60 void build(node * &pt,int l,int r)
61 {
62 pt=new(node);
63 pt->l=l;pt->r=r;pt->val=0;
64 if(l==r)
65 {
66 pt->lc=pt->rc=NULL;
67 return ;
68 }
69 int mid=(l+r)/2;
70 build(pt->lc,l,mid);
71 build(pt->rc,mid+1,r);
72 }
73 void update(node * p,int ps,int val)
74 {
75 if(p->l==p->r)
76 {
77 p->val=val;
78 return ;
79 }
80 int mid=(p->l+p->r)/2;
81 if(ps<=mid)update(p->lc,ps,val);
82 else update(p->rc,ps,val);
83 p->val=max(p->lc->val,p->rc->val);
84 }
85 int query(node * p,int l,int r)
86 {
87 if(l<=p->l&&p->r<=r)return p->val;
88 int mid=(p->l+p->r)/2;
89 int ans=0;
90 if(l<=mid)ans=max(ans,query(p->lc,l,r));
91 if(r>mid)ans=max(ans,query(p->rc,l,r));
92 return ans;
93 }
94 int find(int u,int v)
95 {
96 int tp1=top[u],tp2=top[v],ans=0;
97 while(tp1!=tp2)
98 {
99 if(dep[tp1]<dep[tp2])
100 {
101 swap(tp1,tp2);
102 swap(u,v);
103 }
104 ans=max(ans,query(root,pos[tp1],pos[u]));
105 u=fa[tp1];tp1=top[u];
106 }
107 if(u==v)return ans;
108 if(dep[u]>dep[v])swap(u,v);
109 return max(ans,query(root,pos[u]+1,pos[v]));
110 }
111 int main()
112 {
113 cin>>t;
114 while(t--)
115 {
116 init();
117 scanf("%d",&n);
118 for(int i=1;i<n;i++)
119 {
120 int a,b,c;
121 scanf("%d%d%d",&a,&b,&c);
122 addage(a,b,c);
123 addage(b,a,c);
124 }
125 dfs(1,0,1);
126 getpos(1,1);
127 build(root,1,p);
128 for(int i=1;i<2*n-2;i+=2)
129 {
130 if(dep[e[i].v]<dep[e[i].u])swap(e[i].v,e[i].u);
131 update(root,pos[e[i].v],e[i].w);
132 // cout<<e[i].u<<"------"<<e[i].v<<"-----"<<endl;
133 }
134 char s[10];
135 int u,v;
136 while(scanf("%s",s)==1)
137 {
138 if(s[0]=='D')break;
139 scanf("%d%d",&u,&v);
140 if(s[0]=='Q')printf("%d\n",find(u,v));
141 else update(root,pos[e[u*2-1].v],v);
142 }
143 }
144 return 0;
145 }
QTREE----树剖的更多相关文章
- SP375 QTREE - Query on a tree (树剖)
题目 SP375 QTREE - Query on a tree 解析 也就是个蓝题,因为比较长 树剖裸题(基本上),单点修改,链上查询. 顺便来说一下链上操作时如何将边上的操作转化为点上的操作: 可 ...
- 【61测试】【dp】【二分】【前缀和】【树剖】
不要问我为什么昨天考的今天才贴解题报告.. 第一题: 给定3个字符串,求它们的最长公共子序列. 解: 考试时知道肯定是LCS的二维再加一维,用三维,可天堂有路你不走,地狱无门你偏来...灵机一动想出来 ...
- hdu_5221_Occupation(树剖)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5221 题意:给你一棵树,每个节点有一定的值,有三种操作: 1 x y 表示占领树上x-y的所有节点,2 ...
- 【树链剖分】洛谷P3384树剖模板
题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式 ...
- 【BZOJ 3626】 [LNOI2014]LCA【在线+主席树+树剖】
题目链接: TP 题解: 可能是我比较纱布,看不懂题解,只好自己想了…… 先附一个离线版本题解[Ivan] 我们考虑对于询问区间是可以差分的,然而这并没有什么卵用,然后考虑怎么统计答案. 首先LC ...
- BZOJ_2238_Mst_树剖+线段树
BZOJ_2238_Mst_树剖+线段树 Description 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影 ...
- BZOJ_3626_[LNOI2014]LCA_离线+树剖
BZOJ_3626_[LNOI2014]LCA_离线+树剖 题意: 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1. 设dep[i]表示点i的深度, ...
- BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树
BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树 题意: 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastan ...
- BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树
BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为 ...
- BZOJ_2157_旅游_树剖+线段树
BZOJ_2157_旅游_树剖+线段树 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...
随机推荐
- Zookeeper一致性协议——ZAB
ZAB协议简介 Zookeeper通过ZAB保证分布式事务的最终一致性. ZAB全称Zookeeper Atomic Broadcast(ZAB,Zookeeper原子消息广播协议) ZAB是一种专门 ...
- “开源、共享、创新” 2020 中国.NET开发者大会小结
大会的新闻稿在2020年12月31日正式发布:开源·共享·创新|2020年中国.NET开发者大会圆满收官! , 本文是这篇新闻的补充性文章,仅代表个人对大会的各方面分享内容的一个小结. 在2019年上 ...
- devops持续集成
目录 Devops 版本控制系统 Git安装 Git使用 git四种状态 git基础命令 git分支 git合并冲突 git标签 git命令总结 Github使用 创建仓库 HTTP协议 SSH协议 ...
- windows中关闭端口的方法
打开cmd:输入-ano | findstr "端口号" 控制台会输出占用端口的pid 如"8380" 再向cmd中输入 taskkill /f/pid 838 ...
- Elastisearch在kibana下常用命令总结
1.获取所有数据 GET /_search 2.创建一个Document PUT /ecommerce/product/1 { "name" : "gaolujie ya ...
- 神经网络中的降维和升维方法 (tensorflow & pytorch)
大名鼎鼎的UNet和我们经常看到的编解码器模型,他们的模型都是先将数据下采样,也称为特征提取,然后再将下采样后的特征恢复回原来的维度.这个特征提取的过程我们称为"下采样",这个恢复 ...
- [每日一题]面试官问:谈谈你对ES6的proxy的理解?
[每日一题]面试官问:谈谈你对ES6的proxy的理解? 关注「松宝写代码」,精选好文,每日一题 作者:saucxs | songEagle 一.前言 2020.12.23 日刚立的 flag,每日一 ...
- Spring Security OAuth2.0认证授权二:搭建资源服务
在上一篇文章[Spring Security OAuth2.0认证授权一:框架搭建和认证测试](https://www.cnblogs.com/kuangdaoyizhimei/p/14250374. ...
- Mac最新Flutter环境搭建运行和对比理解声明式UI
前言 这段时间一直都在学习和写关于SwiftUI的东西,前面也总结了四篇文章来大体上说了下Demo中功能实现的一些细节,后面准备开始了解学习一下Flutter,争取在年前能再用Flutter写一份项目 ...
- 魔法方法推开Python进阶学习大门
热爱Python Python是Guido van Rossum设计出来的让使用者觉得如沐春风的一门编程语言.2020年11月12日,64岁的Python之父宣布由于退休生活太无聊,自己决定加入Mic ...