【SPOJ QTREE】树链剖分模板
用线段树求解,这里注意因为求的是路径最大值,注意一下细节。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 10010;
#define lson (pos<<1)
#define rson (pos<<1|1)
const int INF = (1 << 30);
int n;
//--------------------------------------------------
struct Edge{
int to,next;
}edge[MAXN * 2];
int head[MAXN],tot;
int top[MAXN];
int fa[MAXN];
int deep[MAXN];
int num[MAXN];
int p[MAXN];
int fp[MAXN];
int son[MAXN];
int pos;
void init(){
tot = 0;
memset(head,-1,sizeof(head));
pos = 1;
memset(son,-1,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){
deep[u] = d;
fa[u] = pre;
num[u] = 1;
for(int i = head[u]; i != -1; i = edge[i].next){
int v = edge[i].to;
if(v != pre){
dfs1(v,u,d + 1);
num[u] += num[v];
if(son[u] == -1 || num[v] > num[son[u]])
son[u] = v; //找重儿子
}
}
}
void getpos(int u,int sp){
top[u] = sp;
p[u] = pos++;
//printf("%d %d\n",u,p[u]);
fp[p[u]] = u;
if(son[u] == -1) return;
getpos(son[u],sp);
for(int i = head[u]; i != -1; i = edge[i].next){
int v = edge[i].to;
if(v != son[u] && v!= fa[u])
getpos(v,v);
}
}
//----------------------------------------------
int maxv[MAXN << 2]; //该一条边
void build(){
memset(maxv,0,sizeof(maxv));
}
void pushup(int pos){
maxv[pos] = max(maxv[lson],maxv[rson]);
}
void update(int l,int r,int to,int value,int pos){
if(l == r){
maxv[pos] = value;
return;
}
int mid = (l + r) >> 1;
if(to <= mid)
update(l,mid,to,value,lson);
else
update(mid + 1,r,to,value,rson);
pushup(pos);
}
int query(int l,int r,int L,int R,int pos){
if(L <= l && r <= R)
return maxv[pos];
int mid = (l + r) >> 1;
int ret = - INF;
if(L <= mid)
ret = max(ret,query(l,mid,L,R,lson));
if(R > mid)
ret = max(ret,query(mid + 1,r,L,R,rson));
return ret;
}
//-------------------------------------------------------
int find(int u,int v){
int f1 = top[u],f2 = top[v];
int tmp = 0;
while(f1 != f2){
if(deep[f1] < deep[f2]){
swap(f1,f2);
swap(u,v);
}
tmp = max(tmp,query(1,pos,p[f1],p[u],1));
u = fa[f1];
f1 = top[u];
}
if(u == v) return tmp;
if(deep[u] > deep[v]) swap(u,v);
return max(tmp,query(1,pos,p[son[u]],p[v],1));
}
//----------------------------------------------------------
struct E{
int from,to,value;
}e[MAXN];
int main(){
int T;
int u,v;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
init();
for(int i = 0; i < n - 1; i++){
scanf("%d%d%d",&e[i].from,&e[i].to,&e[i].value);
addedge(e[i].from,e[i].to);
addedge(e[i].to,e[i].from);
}
dfs1(1,0,0);
getpos(1,1);
build();
for(int i = 0; i < n - 1; i++){
if(deep[e[i].from] > deep[e[i].to])
swap(e[i].from,e[i].to); //这里是更新一条线段,不是一个点
update(1,pos,p[e[i].to],e[i].value,1);
}
char op[10];
while(scanf("%s",op) != EOF){
if(op[0] == 'D') break;
scanf("%d%d",&u,&v);
if(op[0] == 'Q'){
printf("%d\n",find(u,v));
}
else{
update(1,pos,p[e[u - 1].to],v,1);
}
}
if(T) puts("");
}
return 0;
}
【SPOJ QTREE】树链剖分模板的更多相关文章
- QTREE 树链剖分---模板 spoj QTREE
<树链剖分及其应用> 一文讲得非常清楚,我一早上就把他学会了并且A了这题的入门题. spoj QTREE 题目: 给出一棵树,有两种操作: 1.修改一条边的边权. 2.询问节点a到b的最大 ...
- SPOJ QTREE 树链剖分
树链剖分的第一题,易懂,注意这里是边. #include<queue> #include<stack> #include<cmath> #include<cs ...
- Spoj Query on a tree SPOJ - QTREE(树链剖分+线段树)
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...
- spoj 375 树链剖分模板
/* 只是一道树链刨分的入门题,作为模板用. */ #include<stdio.h> #include<string.h> #include<iostream> ...
- 【学术篇】SPOJ QTREE 树链剖分
发现链剖这东西好久不写想一遍写对是有难度的.. 果然是熟能生巧吧.. WC的dalao们都回来了 然后就用WC的毒瘤题荼毒了我们一波, 本来想打个T1 44分暴力 然后好像是特判写挂了还是怎么的就只能 ...
- spoj 375 树链剖分 模板
QTREE - Query on a tree #tree You are given a tree (an acyclic undirected connected graph) with N no ...
- BZOJ 2243 染色 | 树链剖分模板题进阶版
BZOJ 2243 染色 | 树链剖分模板题进阶版 这道题呢~就是个带区间修改的树链剖分~ 如何区间修改?跟树链剖分的区间询问一个道理,再加上线段树的区间修改就好了. 这道题要注意的是,无论是线段树上 ...
- 算法复习——树链剖分模板(bzoj1036)
题目: 题目背景 ZJOI2008 DAY1 T4 题目描述 一棵树上有 n 个节点,编号分别为 1 到 n ,每个节点都有一个权值 w .我们将以下面的形式来要求你对这棵树完成一些操作:I.CHAN ...
- Hdu 5274 Dylans loves tree (树链剖分模板)
Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...
- SPOJ QTREE - Query on a tree 【树链剖分模板】
题目链接 引用到的大佬博客 代码来自:http://blog.csdn.net/jinglinxiao/article/details/72940746 具体算法讲解来自:http://blog.si ...
随机推荐
- 今日SGU 5.5
SGU 114 题意:求一个点到其他点的距离总和最小,距离的定义是x轴距离乘以那个点的人数p 收获:带权中位数,按坐标排序,然后扫一遍,最后权值超过或等于总权值的一半时的那个点就是答案,证明暂无 #i ...
- 今日SGU 5.3
SGU 107 题意:输入一个N,表示N位数字里面有多少个的平方数的结尾9位是987654321 收获:打表,你发现相同位数的数相乘结果的最后几位,就和那两个相乘的数最后几位相乘一样,比如3416*8 ...
- ln用法
第一部分: 建立简单的硬连接: ln ./wwy.gif ./wwy_ln (第二个参数为新建的连接文件,建立前不存在),则任意一个文件变化,另一个也变化:大小为一个文件的大小:硬连接只能建在同一个分 ...
- leetcode -day29 Binary Tree Inorder Traversal & Restore IP Addresses
1. Binary Tree Inorder Traversal Given a binary tree, return the inorder traversal of its nodes' ...
- Mysql基本增删改查
1登陆服务器 mysql -h localhost -u username -p password 2查看存在数据库 show databases; 3创建一个数据库(例如名字为class1,以下都是 ...
- R语言-上海二手房数据分析
案例:通过分析上海的二手房的数据,分析出性价比(地段,价格,未来的升值空间)来判断哪个区位的二手房性价比最高 1.载入包 library(ggplot2) library(Hmisc) library ...
- 使用NPOI时写的几个辅助方法
简介:包含:获取单元格合并信息GetMergedCellAddress.获取引用单元格字符串ConvertAddressToString.获取单元格字符串格式内容CellValueToString p ...
- subline Text3 安装及汉化
因为自己的subline 有问题 所以决心重新改一下了. 三步: http://www.sublimetext.com/3 官网下载subline3 https://www.imjeff. ...
- 【习题 6-3 UVA - 536】 Tree Recovery
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 递归题 [代码] #include <bits/stdc++.h> using namespace std; const ...
- 硬件——nrf51822第一篇,GPIO的使用
未完,待续...... 本实现是基于一个开发箱,包括:综合应用开发系统主板XT-EDU-AK 1套: 手持终端系统 XT-EDU-HK 1套: GPIO操作 工程: 这是一个关于流水灯的程序: 我 ...