此题绝了,$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.09.23 bzoj1076: [SCOI2008]奖励关(期望+状压dp)

    传送门 一道神奇的期望状压dp. 用f[i][j]f[i][j]f[i][j]表示目前在第i轮已选取物品状态为j,从现在到第k轮能得到的最大贡献. 如果我们从前向后推有可能会遇到不合法的情况. 所以我 ...

  2. Docker swarm结合Openresty部署rabbitmq集群

    Docker swarm结合Openresty部署rabbitmq集群 大家好,年底了,年味儿越来越浓了.2019年的寒冬被定义为未来10年中最好的一年,对于这一说法悲观的人和乐观的人的理解是不一样的 ...

  3. ABP框架 - 缓存( 转)

    出处:http://www.cnblogs.com/kid1412/p/5987083.html 文档目录 本节内容: 简介 ICacheManager ICache ITypedCache 配置 实 ...

  4. gj2 python中一切皆对象

    2.1 python中一切皆是对象 动态语言和静态语言的区别,Python的面向对象更彻底 同时动态语言,代码的灵活性高 没有编译(检查)的过程,错误只有在运行起来后才会发现 函数和类也是对象,属于p ...

  5. python面向对象开发的自我理解

    ​详细代码理解可以参考 笨鸟教程博客:http://www.runoob.com/python3/python3-class.html 面向对象经常被提起,那到底什么是面向对象呢? 它的基本概念:类, ...

  6. The serializable class XXX does not declare a static final serialVersionUID field of type long

    问题: 在Eclipse中,继承类时,总是提示下面的警告(Warning),按理说警告是没有关系的,但是程序看起来老不爽了,这是强迫症的关系(呵呵) The serializable class XX ...

  7. D3 API总览

    D3图形库API参考 https://github.com/d3/d3/wiki/API--%E4%B8%AD%E6%96%87%E6%89%8B%E5%86%8C d3 官网 API https:/ ...

  8. 页面中的删除确认(ajax)、输入框中确认信息是否可用(ajax)的jquery代码

    1.页面中的删除确认(ajax) <%@ page language="java" contentType="text/html; charset=UTF-8&qu ...

  9. OneDrive不能上了?DNS被污染,解决方法很简单

    http://www.expreview.com/34434.html 除了LINE以外,最近微软的OneDrive云存储服务也出现访问故障,不过@月光博客 表示它只是受到DNS污染,被解析为无法访问 ...

  10. linux系统编程之文件与IO(一):文件描述符、open,close

    什么是IO? 输入/输出是主存和外部设备之间拷贝数据的过程 设备->内存(输入操作) 内存->设备(输出操作) 高级I/O ANSI C提供的标准I/O库称为高级I/O,通常也称为带缓冲的 ...