此题绝了,$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. Proximal Algorithms

    1. Introduction Much like Newton's method is a standard tool for solving unconstrained smooth minimi ...

  2. Django入门指南-第6章:第一个视图函数(完结)

    http://127.0.0.1:8000/ # boards/views.py from django.http import HttpResponse from .models import Bo ...

  3. 使用vbs给PPT(包括公式)去背景

    在 视图—>宏 内新建宏 '终极版 Sub ReColor() Dim sld As Slide Dim sh As Shape For Each sld In ActivePresentati ...

  4. FuelPHP 简体中文手册

    FuelPHP中文手册 FuelPHP是一个简单的.灵活的.社区驱动的PHP 5.3 web框架,它基于其他框架的最佳思想,是一个全新的开始. 他的诞生源自于很多开发社区对于现有开发框架的不满,Fue ...

  5. WriteableBitmap(二) 实例

    使用前面定义的WriteableBitmap,我们可以很容易地创建一个足够容纳整个100 x 100图像的数组: byte[] pixels = new byte[wbmap.PixelHeight* ...

  6. struts2从浅至深(二)详细配置

    1.加载时机 当应用被服务器加载时,Struts的配置文件就已经加载了 2.加载顺序 default.properties------->struts-default.xml---------& ...

  7. wxpython 图像编程

    转: http://wxhowto.googlecode.com/svn-history/r6/trunk/body/ch10.tex 的 HTML 档. 使用图像编程 这一章来了解一下我们可以使用图 ...

  8. Android-Java-进程与线程

    1.进程:什么是进程: Mac操作系统,Windows操作系统 ...... 等等,都是由多个进程来运行(系统进程,普通进程,等) 操作系统最小的控制单元是进程,一个应用就是一个进程 进程 全称为:操 ...

  9. CentOS 7 安装MySQL 8.0.11

    1. 下载安装包 wget https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.13-1.el7.x86_64.rpm-bundle.tar 下载 ...

  10. Backup--还原选项之STANDBY

    很多DBA对还原时制定RECOVERY 与 NORECOVERY选项都很熟悉,但是对于STANDBY就有点茫然了,今天一起来学习下吧. --============================== ...