hdu 3804 树链剖分
思路:将边权排序,然后插入线段树,这样就可以直接用二分查找确定答案。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<string>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pb push_back
#define mp make_pair
#define Maxn 100010
#define Maxm 200010
#define LL __int64
#define Abs(x) ((x)>0?(x):(-x))
#define lson(x) (x<<1)
#define rson(x) (x<<1|1)
#define inf 100000
#define lowbit(x) (x&(-x))
#define clr(x,y) memset(x,y,sizeof(x))
#define Mod 1000000007
using namespace std;
int head[Maxn],vi[Maxn],dep[Maxn],w[Maxn],top[Maxn],son[Maxn],sz[Maxn],fa[Maxn],e,id;
int val[Maxn];
int num[Maxn];
struct Point{
int val,i;
int operator <(const Point &temp) const{
return val<temp.val;
}
}lis[Maxn];
struct Edge{
int u,v,next,val;
}edge[Maxn*];
struct Tree{
int l,r,c;
int *p;
int mid(){
return (l+r)>>;
}
}tree[Maxn*];
void init()
{
clr(head,-);clr(vi,);
e=;id=;
for(int i=;i<Maxn*;i++){
delete [] tree[i].p;
}
}
void add(int u,int v,int val)
{
edge[e].u=u,edge[e].v=v,edge[e].val=val,edge[e].next=head[u],head[u]=e++;
}
void BuildTree(int l,int r,int po)
{
tree[po].l=l,tree[po].r=r,tree[po].c=;
tree[po].p=new int[r-l+];
if(l==r)
return ;
int mid=tree[po].mid();
BuildTree(l,mid,lson(po));
BuildTree(mid+,r,rson(po));
}
void update(int i,int c,int po)
{
if(tree[po].l==tree[po].r){
tree[po].p[++tree[po].c]=c;
return ;
}
tree[po].p[++tree[po].c]=c;
int mid=tree[po].mid();
if(i<=mid)
update(i,c,lson(po));
else
update(i,c,rson(po));
}
int getans(int l,int r,int val,int po)
{
if(l<=tree[po].l&&tree[po].r<=r){
int pos=lower_bound(tree[po].p+,tree[po].p+tree[po].c+,val)-tree[po].p;
// cout<<tree[po].l<<" "<<tree[po].r<<" "<<l<<" "<<r
if(pos>tree[po].c)
return tree[po].p[tree[po].c];
if(tree[po].p[pos]==val)
return val;
if(pos>){
return tree[po].p[pos-];
}
return -;
}
int mid=tree[po].mid();
if(r<=mid)
return getans(l,r,val,lson(po));
else if(l>=mid+)
return getans(l,r,val,rson(po));
else{
return max(getans(l,mid,val,lson(po)),getans(mid+,r,val,rson(po)));
}
}
void dfs(int u,int val)
{
vi[u]=;
int i,v;
son[u]=,sz[u]=;
num[u]=val;
for(i=head[u];i!=-;i=edge[i].next){
v=edge[i].v;
if(vi[v]) continue;
dep[v]=dep[u]+;
fa[v]=u;
dfs(v,edge[i].val);
if(sz[v]>sz[son[u]])son[u]=v;
sz[u]+=sz[v];
}
}
void build(int u,int ti)
{
int i,v;
w[u]=++id;top[u]=ti;vi[u]=;
lis[id].i=id,lis[id].val=num[u];
if(son[u]) build(son[u],ti);
for(i=head[u];i!=-;i=edge[i].next){
v=edge[i].v;
if(vi[v]||v==son[u]) continue;
build(v,v);
}
}
void calc(int u,int c)
{
int f1=top[u];
int ans=-;
while(f1!=){
ans=max(ans,getans(w[f1],w[u],c,));
u=fa[f1];f1=top[u];
}
//cout<<w[f1]<<" "<<w[u]<<endl;
ans=max(ans,getans(w[f1],w[u],c,));
printf("%d\n",ans);
return ;
}
int main()
{
int t,n,i,j,u,v,val,q;
scanf("%d",&t);
while(t--){
init();
scanf("%d",&n);
for(i=;i<n;i++){
scanf("%d%d%d",&u,&v,&val);
add(u,v,val);
add(v,u,val);
}
dfs(,);
memset(vi,,sizeof(vi));
build(,);
sort(lis+,lis+id+);
BuildTree(,n,);
for(i=;i<=n;i++){
update(lis[i].i,lis[i].val,);
}
scanf("%d",&q);
for(i=;i<=q;i++){
scanf("%d%d",&u,&v);
calc(u,v);
}
}
return ;
}
hdu 3804 树链剖分的更多相关文章
- hdu 3804树链剖分+离线操作
/* 树链刨分+离线操作 题意:给你一棵树,和询问x,y 从节点x--节点1的小于等于y的最大值. 解:先建一个空树,将树的边权值从小到大排序,将询问y按从小到大排序 对于每次询问y将小于等于y的边权 ...
- hdu 5893 (树链剖分+合并)
List wants to travel Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/O ...
- hdu 5052 树链剖分
Yaoge’s maximum profit Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/ ...
- hdu 4897 树链剖分(重轻链)
Little Devil I Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- hdu 5274 树链剖分
Dylans loves tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- HDU 3966 (树链剖分+线段树)
Problem Aragorn's Story (HDU 3966) 题目大意 给定一颗树,有点权. 要求支持两种操作,将一条路径上的所有点权值增加或减少ai,询问某点的权值. 解题分析 树链剖分模板 ...
- hdu 3966(树链剖分+线段树区间更新)
传送门:Problem 3966 https://www.cnblogs.com/violet-acmer/p/9711441.html 学习资料: [1]线段树区间更新:https://blog.c ...
- HDU 3966 /// 树链剖分+树状数组
题意: http://acm.hdu.edu.cn/showproblem.php?pid=3966 给一棵树,并给定各个点权的值,然后有3种操作: I x y z : 把x到y的路径上的所有点权值加 ...
- hdu 4729 树链剖分
思路:这个树链剖分其实还是比较明显的.将边按权值排序后插入线段树,然后用线段树查找区间中比某个数小的数和,以及这样的数的个数.当A<=B时,就全部建新的管子. 对于A>B的情况比较 建一条 ...
随机推荐
- 新浪SAE数据库信息wordpress设置(用户&密码&主地址)
新浪SAE数据库信息wordpress设置(用户&密码&主地址) 此账号仅能在SAE平台上使用,不能从外部连接我们建议开发者使用SaeMysql操作数据库如果您想自己实现数据库相关操作 ...
- android自定义相册 支持低端机不内存溢出
1 之前在网上看的自定义相册很多时候在低端机都会内存溢出开始上代码把 首先我们要拿到图片的所有路径 cursor = context.getContentResolver().query( Media ...
- C++ Primer 学习笔记_67_面向对象编程 --转换与继承、复制控制与继承
面向对象编程 --转换与继承.复制控制与继承 I.转换与继承 引言: 由于每一个派生类对象都包括一个基类部分,因此能够像使用基类对象一样在派生类对象上执行操作. 对于指针/引用,能够将派生类对象的指针 ...
- java 正则表达式学习
一. Java正则表达式 在程序开发中,难免会遇到需要匹配.查找.替换.判断字符串的情况发生,而这些情况有时又比较复杂. 因此,学习及使用正则表达式,便成了解决这一矛盾的主要手段. 正则表达式是一种可 ...
- Codeforces Round #181 (Div. 2) B. Coach 带权并查集
B. Coach 题目连接: http://www.codeforces.com/contest/300/problem/A Description A programming coach has n ...
- BZOJ 1061: [Noi2008]志愿者招募 费用流
1061: [Noi2008]志愿者招募 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1061 Description 申奥成功后,布布 ...
- Nmap 源代码学习四 软件简单使用
软件安装环境是win7.使用Zenmap, nmap6.49BETA2 扫描主机port nmap -T4 -A -v 192.168.0.207 输出结果: 扫描整个子网 nmap 192.168. ...
- 如何利用PhoneGap制作地图APP
摘要:百度地图API是一套由javascript编写的地图程序接口,按说它应该运行在浏览器上.现在,只要利用PhoneGap,我们就能开发出移动平台上能使用的APP了! --------------- ...
- 有趣的动画视图集合:Android View Animations
Android View Animations这个项目收集了各种有趣的动画效果. 所有效果: Attension Flash, Pulse, RubberBand, Shake, Swing, Wob ...
- Javascript加载执行问题探索
转自:http://www.cnblogs.com/huangxincheng/archive/2011/12/04/2275988.html 前言 最近研究MongoDB数据库,无意间发现的好博客, ...