SPOJ QTREE Query on a Tree【树链剖分模板题】
树链剖分,线段树维护~
- #include <cstdio>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- #include <vector>
- using namespace std;
- const int MAXN = ;
- struct Edge
- {
- int to,next;
- }edge[MAXN*];
- int head[MAXN],tot;
- int top[MAXN];//top[v]表示v所在的重链的顶端节点
- int fa[MAXN]; //父亲节点
- int deep[MAXN];//深度
- int num[MAXN];//num[v]表示以v为根的子树的节点数
- int p[MAXN];//p[v]表示v与其父亲节点的连边在线段树中的位置
- int fp[MAXN];//和p数组相反
- int son[MAXN];//重儿子
- int pos;
- void init()
- {
- tot = ;
- memset(head,-,sizeof(head));
- pos = ;
- memset(son,-,sizeof(son));
- }
- void addedge(int u,int v)
- {
- edge[tot].to = v;edge[tot].next = head[u];head[u] = tot++;
- }
- void dfs1(int u,int pre,int d) //第一遍dfs求出fa,deep,num,son
- {
- deep[u] = d;
- fa[u] = pre;
- num[u] = ;
- for(int i = head[u];i != -; i = edge[i].next)
- {
- int v = edge[i].to;
- if(v != pre)
- {
- dfs1(v,u,d+);
- num[u] += num[v];
- if(son[u] == - || num[v] > num[son[u]])
- son[u] = v;
- }
- }
- }
- void getpos(int u,int sp) //第二遍dfs求出top和p
- {
- top[u] = sp;
- if(son[u] != -)
- {
- p[u] = pos++;
- fp[p[u]] = u;
- getpos(son[u],sp);
- }
- else
- {
- p[u] = pos++;
- fp[p[u]] = u;
- return;
- }
- for(int i = head[u] ; i != -; i = edge[i].next)
- {
- int v = edge[i].to;
- if(v != son[u] && v != fa[u])
- getpos(v,v);
- }
- }
- //线段树
- struct Node
- {
- int l,r;
- int Max;
- }segTree[MAXN*];
- void build(int i,int l,int r)
- {
- segTree[i].l = l;
- segTree[i].r = r;
- segTree[i].Max = ;
- if(l == r)return;
- int mid = (l+r)/;
- build(i<<,l,mid);
- build((i<<)|,mid+,r);
- }
- void push_up(int i)
- {
- segTree[i].Max = max(segTree[i<<].Max,segTree[(i<<)|].Max);
- }
- void update(int i,int k,int val) // 更新线段树的第k个值为val
- {
- if(segTree[i].l == k && segTree[i].r == k)
- {
- segTree[i].Max = val;
- return;
- }
- int mid = (segTree[i].l + segTree[i].r)/;
- if(k <= mid)update(i<<,k,val);
- else update((i<<)|,k,val);
- push_up(i);
- }
- int query(int i,int l,int r) //查询线段树中[l,r] 的最大值
- {
- if(segTree[i].l == l && segTree[i].r == r)
- return segTree[i].Max;
- int mid = (segTree[i].l + segTree[i].r)/;
- if(r <= mid)return query(i<<,l,r);
- else if(l > mid)return query((i<<)|,l,r);
- else return max(query(i<<,l,mid),query((i<<)|,mid+,r));
- }
- int find(int u,int v)//查询u->v边的最大值
- {
- int f1 = top[u], f2 = top[v];
- int tmp = ;
- while(f1 != f2)
- {
- if(deep[f1] < deep[f2])
- {
- swap(f1,f2);
- swap(u,v);
- }
- tmp = max(tmp,query(,p[f1],p[u]));
- u = fa[f1]; f1 = top[u];
- }
- if(u == v)return tmp;
- if(deep[u] > deep[v]) swap(u,v);
- return max(tmp,query(,p[son[u]],p[v]));
- }
- int e[MAXN][];
- int main()
- {
- //freopen("in.txt","r",stdin);
- //freopen("out.txt","w",stdout);
- int T;
- int n;
- scanf("%d",&T);
- while(T--)
- {
- init();
- scanf("%d",&n);
- for(int i = ;i < n-;i++)
- {
- scanf("%d%d%d",&e[i][],&e[i][],&e[i][]);
- addedge(e[i][],e[i][]);
- addedge(e[i][],e[i][]);
- }
- dfs1(,,);
- getpos(,);
- build(,,pos-);
- for(int i = ;i < n-; i++)
- {
- if(deep[e[i][]] > deep[e[i][]])
- swap(e[i][],e[i][]);
- update(,p[e[i][]],e[i][]);
- }
- char op[];
- int u,v;
- while(scanf("%s",op) == )
- {
- if(op[] == 'D')break;
- scanf("%d%d",&u,&v);
- if(op[] == 'Q')
- printf("%d\n",find(u,v));
- else update(,p[e[u-][]],v);
- }
- }
- return ;
- }
SPOJ QTREE Query on a Tree【树链剖分模板题】的更多相关文章
- spoj QTREE - Query on a tree(树链剖分+线段树单点更新,区间查询)
传送门:Problem QTREE https://www.cnblogs.com/violet-acmer/p/9711441.html 题解: 树链剖分的模板题,看代码比看文字解析理解来的快~~~ ...
- SPOJ QTREE Query on a tree ——树链剖分 线段树
[题目分析] 垃圾vjudge又挂了. 树链剖分裸题. 垃圾spoj,交了好几次,基本没改动却过了. [代码](自带常数,是别人的2倍左右) #include <cstdio> #incl ...
- SPOJ QTREE Query on a tree 树链剖分+线段树
题目链接:http://www.spoj.com/problems/QTREE/en/ QTREE - Query on a tree #tree You are given a tree (an a ...
- SPOJ QTREE Query on a tree --树链剖分
题意:给一棵树,每次更新某条边或者查询u->v路径上的边权最大值. 解法:做过上一题,这题就没太大问题了,以终点的标号作为边的标号,因为dfs只能给点分配位置,而一棵树每条树边的终点只有一个. ...
- SPOJ 375 Query on a tree 树链剖分模板
第一次写树剖~ #include<iostream> #include<cstring> #include<cstdio> #define L(u) u<&l ...
- spoj 375 QTREE - Query on a tree 树链剖分
题目链接 给一棵树, 每条边有权值, 两种操作, 一种是将一条边的权值改变, 一种是询问u到v路径上最大的边的权值. 树链剖分模板. #include <iostream> #includ ...
- SPOJ Query on a tree 树链剖分 水题
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...
- spoj 375 Query on a tree (树链剖分)
Query on a tree You are given a tree (an acyclic undirected connected graph) with N nodes, and edges ...
- Query on a tree 树链剖分 [模板]
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...
- Hdu 5274 Dylans loves tree (树链剖分模板)
Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...
随机推荐
- AcWing 8.二维费用的背包问题
#include<iostream> #include<algorithm> #include<cstring> using namespace std ; ; i ...
- Java爬虫学习(3)之用对象保存新浪微博博文
package com.mieba; import us.codecraft.webmagic.Page; import us.codecraft.webmagic.Site; import us.c ...
- 生产环境设置mysql主从复制
Slave服务器的版本要等于或者高于master服务器 现在的实例是在mysql 5.7上的主从配置 a) master服务器的my.cnf配置,server_id 推荐用IP的后两位数字 [mysq ...
- AJAX--XMLHttpRequest对象
创建XMLHttpRequest对象 XMLHttpRequest是AJAX的基础. 所有现代浏览器(IE7+.Firefox.Chrome.Safari以及Opera)均内建XMLHttpReque ...
- 按需引入element-ui时修改.babelrc报错
刚开始学习element-ui时用的都是完整引入,图省事,这次准备按需引入,以减小项目体积, 乙烯类npm 之后,到了修改 .babelrc 文件这一步(PS:vue-cli 2.0版本会有这个文件, ...
- 【网易官方】极客战记(codecombat)攻略-地牢-恐惧之门
关卡连接: https://codecombat.163.com/play/level/dread-door 恐惧之门后藏满宝藏 简介: while-true 循环可以使用任何方法,如: while ...
- AndroidStudio3.3+OpenCV开发环境搭建
创建一个Android Studio普通项目 导入module 选择 File → New → Import Module 选择解压好的opencv-android-sdk下的sdk下的java,点O ...
- oracle建表时出现“标识符无效”错误
oracle用以下sql语句新建表时,出现"标识符无效"错误: create table users( user_id integer not null, user_name va ...
- 生成树计数 lighting 最终决定用这个模板! (有逆元的模板)
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> # ...
- java.lang.IllegalStateException: Illegal access: this web application instance has been stopped already. Could not load [META-INF/services/com.alibaba.druid.filter.Filter].
九月 11, 2019 2:56:36 下午 org.apache.catalina.loader.WebappClassLoaderBase checkStateForResourceLoading ...