题目内容:

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

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. 移动端学习之理解WEB APP、Native APP、Hybrid APP以及React Native/uniapp包括H5、小程序等的区别与共通之处

    因为工作需要,需要进一步了解移动端的开发,遂返回复习移动端的知识点,在开始学习之前,产生了疑惑WEB APP .Native APP .Hybrid APP.React Native.Uniapp.H ...

  2. C语言基础二维数组

    (1)二位数组的定义int array[n][m],行下标的取值范围是0~n-1,列下标的取值范围是0~m-1,二维数组最大下标元素是array[n-1][m-1]:如定义一个3行4列的数组 int ...

  3. Apache本机不同端口多站点配置:httpd-vhosts.conf(转载)

    环境:Apache2.2.9,Resin-3.1.6,Win Server 2003 1.解压Resin至任意目录,我的是D:; 2. 安装Apache,具体操作下一步.下一步即可,其中要配置的地方是 ...

  4. MySQL中in('5,6,7')只取第一个id为5对应的数据的思考

    通过阅读本文你可以更好的理解两个知识点: 1.#{}与${}在实际项目中的使用,避免在项目中使用不当造成不可预知的Bug; 2.MySQL中in里面如果是字符串的话,为什么只取第一个对应的数据,eg: ...

  5. 网络设置-指定ip

    1 克隆centos6.设置网卡 vim /etc/udev/rules.d/70-persistent-net.rules 确定光标所在的位置 d3d删除以下三行,更改NAME为0 vim /etc ...

  6. Tomca7t服务器 配置HTTP和HTTPS 同时访问

    (首先你要有 ssl 证书 ,我是阿里的 ) 查看申请ssl证书(https://www.cnblogs.com/lxf-mw/p/14261303.html) 一.下载 tomcat证书(两个文件) ...

  7. 一个上传图片,预览图片的小demo

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. js原型链原理

    先附上原型链的图,能看懂的本文就没必要看了,看不懂的可以带着疑问看文章 一.构造函数 什么是构造函数:当一个普通函数创建一个类对象是,那么就程它为构造函数. 特点: 默认首字母大写 使用new关键字来 ...

  9. kubernetes环境部署单节点redis

    kubernetes部署redis数据库(单节点) redis简介 Redis 是我们常用的非关系型数据库,在项目开发.测试.部署到生成环境时,经常需要部署一套 Redis 来对数据进行缓存.这里介绍 ...

  10. 修改hosts文件后不生效,该怎么办

    对于web开发来说,经常需要修改hosts文件,用来将域名与ip对应匹配.但是有时候发现hosts文件明明已经改了,但就是不生效,页面还会跳到某个丧心病狂的私人小站.hosts文件不生效有很多种原因, ...