题目内容:

————————————————————————————————————————————————————

Time Limit: 851MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu

Submit Status

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 ab 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----树剖的更多相关文章

  1. SP375 QTREE - Query on a tree (树剖)

    题目 SP375 QTREE - Query on a tree 解析 也就是个蓝题,因为比较长 树剖裸题(基本上),单点修改,链上查询. 顺便来说一下链上操作时如何将边上的操作转化为点上的操作: 可 ...

  2. 【61测试】【dp】【二分】【前缀和】【树剖】

    不要问我为什么昨天考的今天才贴解题报告.. 第一题: 给定3个字符串,求它们的最长公共子序列. 解: 考试时知道肯定是LCS的二维再加一维,用三维,可天堂有路你不走,地狱无门你偏来...灵机一动想出来 ...

  3. hdu_5221_Occupation(树剖)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5221 题意:给你一棵树,每个节点有一定的值,有三种操作: 1 x y 表示占领树上x-y的所有节点,2 ...

  4. 【树链剖分】洛谷P3384树剖模板

    题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式 ...

  5. 【BZOJ 3626】 [LNOI2014]LCA【在线+主席树+树剖】

    题目链接: TP 题解:   可能是我比较纱布,看不懂题解,只好自己想了…… 先附一个离线版本题解[Ivan] 我们考虑对于询问区间是可以差分的,然而这并没有什么卵用,然后考虑怎么统计答案. 首先LC ...

  6. BZOJ_2238_Mst_树剖+线段树

    BZOJ_2238_Mst_树剖+线段树 Description 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影 ...

  7. BZOJ_3626_[LNOI2014]LCA_离线+树剖

    BZOJ_3626_[LNOI2014]LCA_离线+树剖 题意: 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1. 设dep[i]表示点i的深度, ...

  8. BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树

    BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树 题意: 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastan ...

  9. BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树

    BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为 ...

  10. BZOJ_2157_旅游_树剖+线段树

    BZOJ_2157_旅游_树剖+线段树 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...

随机推荐

  1. MRP物料需求计划

    1.重订货点的采购计划. 计算方式:再订货点的库存数量 = 安全库存 + 采购提前期 * 每天消耗的数量 一旦库存数量触及再订货点的库存数量,需触发采购订单订购物料,理想的情况下 ,下次到采购订单收货 ...

  2. 前台生成JSON

    方法一 :在后台需要转换String - json let param = new URLSearchParams(); param.append('username', this.username) ...

  3. Android基本组件TextView和EditView

    1.TextView 用于在屏幕上显示文本,可以显示单行文本,多行文本,和带图像的文本. 常用xml属性 (1)android:autoLink,用于指定是否将指定的文本转换为可单机的超链接形式,其属 ...

  4. 商品类型的下拉框绑定一个事件,通过ajax获取属性

    html代码这么写 <!-- 商品属性 --> <table cellspacing="1" cellpadding="3" width=&q ...

  5. 巧用 Lazy 解决.NET Core中的循环依赖关系

    原文作者: Thomas Levesque 原文链接:https://thomaslevesque.com/2020/03/18/lazily-resolving-services-to-fix-ci ...

  6. OpenOCD安装与使用(JTAG调试)

    本文介绍openocd开源软件的安装以及搭配JTAG对Xilinx u500VC707devkit的调试 PC OS: Ubuntu20.04 LTS Target ARCH: riscv64 JTA ...

  7. (解决)easypoi模板导出多个excel文件并压缩

    目录 easypoi版本--3.1.0 实现代码 后语 easypoi版本--3.1.0 实现代码 public void export(HttpServletResponse response, H ...

  8. docker 数据卷的挂载和使用

    容器之间的数据共享技术, Docker容器产生的数据同步到本地 卷技术 --> 目录挂载, 将容器内的目录挂载到服务器上 使用命令来挂载 -v # 可以挂载多个目录 docker run -it ...

  9. 【TOMCAT】windows7下tomcat6环境部署

    首先,下载一个tomcat6的部署包 地址http://download.csdn.net/download/imliuqun123/10156942 需要部署安装的win7环境变量: 1.jdk环境 ...

  10. Python利用最优化算法求解投资内部收益率IRR【一】

    一. 内部收益率和净现值 内部收益率(Internal Rate of Return, IRR)其实要和净现值(Net Present Value, NPV)结合起来讲.净现值指的是某个投资项目给公司 ...