此题绝了,$O(n^{1.5}\ log\ n)$都可以过掉。。。。

题目大意:给你一颗$n$个点的树,每条边边权不是2就是$1$,有$m$个询问,每次询问一个人从$x$点走到$y$点,每天可以走的里程数不超过$k$,问你从$x$至$y$至少需几天。

数据范围:$n≤10^5$。

我们将询问分成$k≤\sqrt{n}$和k$>\sqrt{n}$两类。

对于$k>\sqrt{n}$的,每次跳跃我们直接大力倍增就可以了,不难发现此方法单次的时间复杂度为$O(\sqrt{n}log\  n)$。

对于$k≤\sqrt{n}$的,我们将$k$相同的分为一类,令$g[i][j]$表示从i往根走$2^j$天走到的位置,然后大力倍增就可以了,不难发现单次倍增找答案的时间复杂度是$O(log\ n)$的,重建一次倍增数组的时间复杂度是$O(n\ log\  n)$的,总时间复杂度为$O(n^{1.5}\ log n+m\ log n)$。

如此粗暴的做法居然能在$350ms$跑过去,真是绝了(敢写敢过。。。。)

 #include<bits/stdc++.h>
#define M 100005
#define N 17
using namespace std;
struct edge{int u,v,next;}e[M*]={}; int head[M]={},use=;
void add(int x,int y,int z){use++;e[use].u=y;e[use].v=z;e[use].next=head[x];head[x]=use;}
int f[M][N]={},dep[M]={},dis[M]={};
void dfs(int x,int fa,int hh){
f[x][]=fa; dep[x]=dep[fa]+; dis[x]=dis[fa]+hh;
for(int i=;i<N;i++) f[x][i]=f[f[x][i-]][i-];
for(int i=head[x];i;i=e[i].next) if(e[i].u!=fa) dfs(e[i].u,x,e[i].v);
}
int getlca(int x,int y){
if(dep[x]<dep[y]) swap(x,y); int cha=dep[x]-dep[y];
for(int i=N-;~i;i--) if((<<i)&cha) x=f[x][i];
for(int i=N-;~i;i--) if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
if(x==y) return x; return f[x][];
}
int getdis(int x,int y){return dis[x]+dis[y]-*dis[getlca(x,y)];}
int _j=;
int jumpdn(int x,int y,int d){
int now=dis[y]-dis[x]; if(now<=d) return y;
for(int i=N-;~i;i--)
if(dis[f[y][i]]-dis[x]>=d)
y=f[y][i];
if(dis[y]-dis[x]>d) y=f[y][];
return y;
}
int jumpup(int x,int y,int d){
if(y){
int lca=getlca(x,y); _j=;
if(dis[x]-dis[lca]<=d){
d-=dis[x]-dis[lca]; _j=;
return jumpdn(lca,y,d);
}
}
for(int i=N-;~i;i--) if(dis[x]-dis[f[x][i]]<=d) d-=dis[x]-dis[f[x][i]],x=f[x][i];
return x;
}
int g[M][N]={},D=;
void dfs(int x,int fa){
g[x][]=jumpup(x,,D); for(int i=;i<N;i++) g[x][i]=g[g[x][i-]][i-];
for(int i=head[x];i;i=e[i].next) if(e[i].u!=fa) dfs(e[i].u,x);
}
int query(int &x,int lca){int res=;
for(int i=N-;~i;i--){
if(dis[x]-dis[lca]<D) return res;
if(dep[g[x][i]]>=dep[lca]) x=g[x][i],res+=<<i;
}
return res;
}
int n,m,sq;
struct ask{
int x,y,d,id; ask(){x=y=d=id=;}
void rd(int ID){id=ID; scanf("%d%d%d",&x,&y,&d);}
friend bool operator <(ask a,ask b){return a.d<b.d;}
int query1(){
if(x==y) return ;
int lca=getlca(x,y),res=; _j=;
while(_j==) x=jumpup(x,y,d),res++;
while(x!=y) x=jumpdn(x,y,d),res++;
return res;
}
int query2(){
int lca=getlca(x,y),res=;
if(D!=d){D=d;dfs(,);}
res+=query(x,lca);
res+=query(y,lca);
res+=(getdis(x,y)>D)+(getdis(x,y)>);
return res;
}
}p[M]; int ans[M]={};
int main(){
scanf("%d",&n); sq=(n<=?:);
for(int i=,x,y,z;i<n;i++) scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z);
dfs(,,); dis[]=-;
scanf("%d",&m);
for(int i=;i<=m;i++) p[i].rd(i);
sort(p+,p+m+);
for(int i=;i<=m;i++){
if(p[i].d<=sq) ans[p[i].id]=p[i].query2();
else ans[p[i].id]=p[i].query1();
}
for(int i=;i<=m;i++) printf("%d\n",ans[i]);
}

【CODECHEF】Children Trips 倍增的更多相关文章

  1. [CC-TRIPS]Children Trips

    [CC-TRIPS]Children Trips 题目大意: \(n(n\le10^5)\)座城市构成一棵树,且树上的每条边的长度\(l_i\)满足\(1\le l_i\le 2\).\(m(m\le ...

  2. Codechef TRIPS Children Trips (分块、倍增)

    题目链接: https://www.codechef.com/problems/TRIPS 感觉CC有点毒瘤啊.. 题解: 首先有一个性质可能是因为太傻所以网上没人解释,然而我看了半天: 就是正序和倒 ...

  3. CODECHEF Oct. Challenge 2014 Children Trips

    @(XSY)[分塊, 倍增] Description There's a new trend among Bytelandian schools. The "Byteland Tourist ...

  4. 【codechef】Children Trips

    Portal -->CC_Children Trips Solution (英文题解看得真爽qwq不过写的好详细啊ovo) 首先这题有一个很重要的条件就是边权是\(1\)或者\(2\),所以虽然 ...

  5. 题解 Children Trips

    题目传送门 Description 给出一个大小为 \(n\) 的边权全为 \(1,2\) 的带权树,有 \(q\) 此查询,每次给出 \(u,v,p\) ,问 \(u\to v\) 每次可以最多走边 ...

  6. CodeChef TRIPS-Children Trips 树上分块

    参考文献国家集训队2015论文<浅谈分块在一类在线问题的应用>-邹逍遥 题目链接 题目大意 一棵n个节点的树,树的每条边长度为1或2,每次询问x,y,z. 要求输出从x开始走,每次只能走到 ...

  7. Codechef April Challenge 2019 游记

    Codechef April Challenge 2019 游记 Subtree Removal 题目大意: 一棵\(n(n\le10^5)\)个结点的有根树,每个结点有一个权值\(w_i(|w_i\ ...

  8. 「Codechef April Lunchtime 2015」Palindromeness

    「Codechef April Lunchtime 2015」Palindromeness 解题思路 : 考虑对于回文子串 \(s\) 贡献的定义: \[ value_s = [\ s[1,\lflo ...

  9. 后缀数组的倍增算法(Prefix Doubling)

    后缀数组的倍增算法(Prefix Doubling) 文本内容除特殊注明外,均在知识共享署名-非商业性使用-相同方式共享 3.0协议下提供,附加条款亦可能应用. 最近在自学习BWT算法(Burrows ...

随机推荐

  1. 2018.10.13 bzoj4008: [HNOI2015]亚瑟王(概率dp)

    传送门 马上2点考初赛了,心里有点小紧张. 做道概率dp压压惊吧. 话说这题最开始想错了. 最开始的方法是考虑f[i][j]f[i][j]f[i][j]表示第iii轮出牌为jjj的概率. 然后用第ii ...

  2. 2018.07.04 POJ 1265 Area(计算几何)

    Area Time Limit: 1000MS Memory Limit: 10000K Description Being well known for its highly innovative ...

  3. hdu-1130(卡特兰数+大数乘法,除法模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1130 卡特兰数:https://blog.csdn.net/qq_33266889/article/d ...

  4. [GO]删除切片的某个值

    func removePro(ddbenv []*model.EnvInfo, k int) []*model.EnvInfo { :]...) } for k, v := range ddbenv ...

  5. Java基础知识学习笔记(一)

    理解面向对象: Java纯粹的面向对象的程序设计语言,主要表现为Java完全支持面向对象的三个基本特征:继承.封装.多态. Java程序的最小单位是类,类代表客观世界中具有某种特征的一类事物,这些类可 ...

  6. IntelliJ IDEA 2017版 SpringBoot的核心配置详解

    Spring Boot的核心   (1)Spring Boot的项目一般都会有*Application的入口类,入口类中会有main方法,这是一个标准的Java应用程序的入口方法.  (2)@Spri ...

  7. windows下命令提示符中有空格路径的解决方法

    1)用缩写.比如c:\Program Files 缩写为c:\Progra~1 再来刨根问底查查这个命名是否有规则,于是找到: 文件夹(sub-directry)名称,以前是不允许带空白的,后来允许带 ...

  8. 201709018工作日记--RecyclerView的使用(点击,瀑布流的实现)

    参考相关博客: http://www.jianshu.com/p/55e3f1b6701f  刘望舒 http://www.jianshu.com/p/4fc6164e4709 王三的猫阿德 http ...

  9. Robotframework 简介及工作原理

    下面通过官网和网上资料来简单介绍下Robotframework及其工作原理. 官方说明: Robot Framework is a generic test automation framework ...

  10. 从0学习JQ

    转 张子秋的博客 为以后用到的时候好查询! 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 ...