题目链接:

http://codeforces.com/gym/101161/attachments

题意:

给出节点数为$n$的树

有$q$次询问,输出$a$节点到$b$节点路程中,经过的边的中位数

数据范围:

$1\leq n \leq 100000$

$1\leq q \leq 100000$

分析:

建一颗主席树,不同的是,节点的根继承的是父节点的根

再用$lca$求出公共祖先$tree[a]+tree[b]-2*tree[lca(a,b)]$

ac代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
const int maxn = 5e4+100;
struct Node{
int L,R,num;
}tree[maxn*20];
int dep[maxn],fa[maxn][20],n,cnt;
int root[maxn],vis[maxn];
vector<pii>ve[maxn]; void update(int x,int&root,int st,int en){
tree[++cnt]=tree[root];
root=cnt;
tree[root].num++;
if(st==en)return ;
int md=(st+en)/2;
if(x<=md)
update(x,tree[root].L,st,md);
else
update(x,tree[root].R,md+1,en);
} void dfs(int x,int fx,int w){
if(vis[x])return ;
vis[x]=1;
root[x]=root[fx];
if(x!=1)update(w,root[x],1,1e5);
dep[x]=dep[fx]+1;
fa[x][0]=fx;
for(int i=1;(1<<i)<dep[x];i++)
fa[x][i]=fa[fa[x][i-1]][i-1];
for(int i=0;i<ve[x].size();i++)
dfs(ve[x][i].first,x,ve[x][i].second);
}
int lca(int a,int b){
if(dep[a]>dep[b])swap(a,b);
for(int i=19;i>=0;i--)
if(dep[fa[b][i]]>=dep[a])b=fa[b][i];
if(a==b)return a;
for(int i=19;i>=0;i--)
if(fa[a][i]!=fa[b][i])a=fa[a][i],b=fa[b][i];
return fa[a][0];
} int quer(int a,int b,int c,int st,int en,int k){
if(st==en)return st;
int dd=tree[tree[a].L].num+tree[tree[b].L].num-2*tree[tree[c].L].num;
//cout<<dd<<" "<<k<<endl;
int md=(st+en)/2;
if(dd>=k)return quer(tree[a].L,tree[b].L,tree[c].L,st,md,k);
return quer(tree[a].R,tree[b].R,tree[c].R,md+1,en,k-dd);
}
int main()
{
int T,q;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
cnt=0;
for(int i=1;i<=n;i++){
ve[i].clear();
vis[i]=0;
for(int j=0;j<20;j++)
fa[i][j]=0;
}
for(int i=1;i<=n-1;i++){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
ve[a].push_back(make_pair(b,c));
ve[b].push_back(make_pair(a,c));
} dfs(1,0,-1);
//cout<<fa[6][2]<<endl;
scanf("%d",&q);
while(q--){
int a,b,c;
scanf("%d %d",&a,&b);
c=lca(a,b);
int len=dep[a]+dep[b]-2*dep[c];
//cout<<c<<" "<<len<<endl;
if(len%2==0){
int ans1=quer(root[a],root[b],root[c],1,1e5,len/2);
int ans2=quer(root[a],root[b],root[c],1,1e5,len/2+1);
printf("%d",(ans1+ans2)/2);
if((ans1+ans2)%2)printf(".5");
else printf(".0");
}
else
printf("%d.0",quer(root[a],root[b],root[c],1,1e5,len/2+1));
printf("\n");
}
}
return 0;
}

  

codeforces gym #101161E - ACM Tax(lca+主席树)的更多相关文章

  1. Codeforces Gym101161E:ACM Tax(主席树+LCA)

    题目链接 题意 给出一棵有边权的树,然后给出q个查询,每次查询问两个结点的路径上的边的长度的中位数是多少. 思路 这道题目是用主席树(用权值当结点)和LCA来做的. 和之前做过的区间第K大类似,这道题 ...

  2. UVALive - 7831 :ACM Tax (主席树求树路径上中位数:LCA+主席树)

    题意:给定一棵带权树,Q次询问,每次询问路径上的中位数. 思路:中位数分边数奇偶考虑,当当边数为num=奇时,结果就算路径第num/2+1大,用主席树做即可... (做了几道比较难的主席树,都wa了. ...

  3. Gym101161:ACM Tax (主席树)(占位)

    题意:给定一个带权树,Q次询问,每次回答某简单路径上的权值中位数. 思路:记录根到节点的主席树,主席树可以找到路径的第K大权值.(记住,这里是可以不用二分的,不要想多了.) 奇数条边直接找中位数,偶数 ...

  4. LCA+主席树 (求树上路径点权第k大)

      SPOJ 10628. Count on a tree (树上第k大,LCA+主席树) 10628. Count on a tree Problem code: COT You are given ...

  5. 【bzoj3123】[Sdoi2013]森林 倍增LCA+主席树+启发式合并

    题目描述 输入 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负 ...

  6. SPOJ 10628 Count on a tree(Tarjan离线LCA+主席树求树上第K小)

    COT - Count on a tree #tree You are given a tree with N nodes.The tree nodes are numbered from 1 to  ...

  7. 【SPOJ】10628. Count on a tree(lca+主席树+dfs序)

    http://www.spoj.com/problems/COT/ (速度很快,排到了rank6) 这题让我明白了人生T_T 我知道我为什么那么sb了. 调试一早上都在想人生. 唉. 太弱. 太弱. ...

  8. BZOJ2588Count on a tree——LCA+主席树

    题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...

  9. spoj COT - Count on a tree (树上第K小 LCA+主席树)

    链接: https://www.spoj.com/problems/COT/en/ 思路: 首先看到求两点之前的第k小很容易想到用主席树去写,但是主席树处理的是线性结构,而这道题要求的是树形结构,我们 ...

随机推荐

  1. (五)Hibernate的增删改查操作(2)

    接上一章节 HQL的预编译语句 HIbernate中的预编译与Spring的预编译的处理差不多.    1:使用标准的?  2:使用命名参数   2.1:使用名称逐个设置.   2.2:使用Map(k ...

  2. leetcode --165--php

    class Solution { /** * @param String $version1 * @param String $version2 * @return Integer */ functi ...

  3. LeetCode 1047. Remove All Adjacent Duplicates In String

    1047. Remove All Adjacent Duplicates In String(删除字符串中的所有相邻重复项) 链接:https://leetcode-cn.com/problems/r ...

  4. 在论坛中出现的比较难的sql问题:4(row_number函数+子查询 分组连续编号问题)

    原文:在论坛中出现的比较难的sql问题:4(row_number函数+子查询 分组连续编号问题) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路. 求一查询语句 http: ...

  5. iOS 如何判断一个点在圆、方框、三角形区域内?

    如何判断一个点是不是在方框(CGRect).圆(Circle).三角形(Triangle)内呢? 1.方框 //苹果官方方法可以判断 + (BOOL)point:(CGPoint)point inSq ...

  6. 解决spring-boot-maven-plugin插件打包,springboot启动时报找不到主main问题

    一:遇到的问题及解决方法 最近在搭建一个新项目时,使用spring-boot-maven-plugin插件打包,springboot项目在发布后启动时遇到找不到主main问题. 遇到这个问题当时感觉本 ...

  7. CSS3 filter滤镜

    其默认值是none,他不具备继承性,其中filter-function一个具有以下值可选: grayscale灰度 sepia褐色(求专业指点翻译) saturate饱和度 hue-rotate色相旋 ...

  8. 用java代码实现

    用java代码实现(1)珠穆朗玛峰高度为8848米,有一张足够大的纸,厚度为0.001米. (2)请问,我折叠多少次,可以折成珠穆朗玛峰的高度/** * @author 18269 * @date 2 ...

  9. Mysql实现数据库主从复制架构

    MySQL复制 (1)扩展方式: Scale Up ,Scale Out (2)MySQL的扩展 读写分离 复制:每个节点都有相同的数据集 向外扩展 二进制日志 单向 (3)复制的功用: 数据分布 负 ...

  10. 用python文件操作实现复制图片、视频

    图片复制 打开源图片: f_src = open('1.jpg','rb') 读取图片内容并存储到content变量 content = f_src.read() 打开复制后的图片,没有则创建 f_c ...