【CODECHEF】Children Trips 倍增
此题绝了,$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 倍增的更多相关文章
- [CC-TRIPS]Children Trips
[CC-TRIPS]Children Trips 题目大意: \(n(n\le10^5)\)座城市构成一棵树,且树上的每条边的长度\(l_i\)满足\(1\le l_i\le 2\).\(m(m\le ...
- Codechef TRIPS Children Trips (分块、倍增)
题目链接: https://www.codechef.com/problems/TRIPS 感觉CC有点毒瘤啊.. 题解: 首先有一个性质可能是因为太傻所以网上没人解释,然而我看了半天: 就是正序和倒 ...
- CODECHEF Oct. Challenge 2014 Children Trips
@(XSY)[分塊, 倍增] Description There's a new trend among Bytelandian schools. The "Byteland Tourist ...
- 【codechef】Children Trips
Portal -->CC_Children Trips Solution (英文题解看得真爽qwq不过写的好详细啊ovo) 首先这题有一个很重要的条件就是边权是\(1\)或者\(2\),所以虽然 ...
- 题解 Children Trips
题目传送门 Description 给出一个大小为 \(n\) 的边权全为 \(1,2\) 的带权树,有 \(q\) 此查询,每次给出 \(u,v,p\) ,问 \(u\to v\) 每次可以最多走边 ...
- CodeChef TRIPS-Children Trips 树上分块
参考文献国家集训队2015论文<浅谈分块在一类在线问题的应用>-邹逍遥 题目链接 题目大意 一棵n个节点的树,树的每条边长度为1或2,每次询问x,y,z. 要求输出从x开始走,每次只能走到 ...
- Codechef April Challenge 2019 游记
Codechef April Challenge 2019 游记 Subtree Removal 题目大意: 一棵\(n(n\le10^5)\)个结点的有根树,每个结点有一个权值\(w_i(|w_i\ ...
- 「Codechef April Lunchtime 2015」Palindromeness
「Codechef April Lunchtime 2015」Palindromeness 解题思路 : 考虑对于回文子串 \(s\) 贡献的定义: \[ value_s = [\ s[1,\lflo ...
- 后缀数组的倍增算法(Prefix Doubling)
后缀数组的倍增算法(Prefix Doubling) 文本内容除特殊注明外,均在知识共享署名-非商业性使用-相同方式共享 3.0协议下提供,附加条款亦可能应用. 最近在自学习BWT算法(Burrows ...
随机推荐
- Warning: Attempt to present A on B whose view is not in the window hierarchy!
昨天写豆瓣发广播Demo的时候,为了写Demo的简单,就使用了Storyboard,结果执行视图跳转时遇到了这个问题: Warning: Attempt to present <UINaviga ...
- 多网卡的7种bond模式原理 For Linux
多网卡的7种bond模式原理 Linux 多网卡绑定 网卡绑定mode共有七种(0~6) bond0.bond1.bond2.bond3.bond4.bond5.bond6 常用的有三种 mode=0 ...
- 实体类在set字段时报空指针异常
实体类在set字段时报空指针异常的原因: T_Entry entry=null;entry.setGeneName("1212");entry.setEntryName(" ...
- 2018.08.29 NOIP模拟 table(拓扑排序+建图优化)
[描述] 给出一个表格,N 行 M 列,每个格子有一个整数,有些格子是空的.现在需要你 来做出一些调整,使得每行都是非降序的.这个调整只能是整列的移动. [输入] 第一行两个正整数 N 和 M. 接下 ...
- java redis基本操作
package com.redis; import java.util.ArrayList;import java.util.Iterator;import java.util.List;import ...
- Netty学习第五节实例进一步学习
概念理解: Netty是基于NIO的框架 传统IO与NIO的区别: 1.传统IO会造成阻塞点: 2.单一的客户端处理消息 解决阻塞问题:建立线程池,达到收到一个消息就建立一个 ...
- 20155218 2016-2017-2 《Java程序设计》第6周学习总结
20155218 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 Java将输入/输出抽象化为串流,数据有来源及目的地,衔接两者的是串流对象. dump()方 ...
- 14)settings.xml
1. User Level. ${user.home}/.m2/settings.xml 2. Global Level. ${maven.home}/conf/settings.xml <se ...
- iOS平台设置系统状态栏(通知栏、顶部状态栏)样式背景颜色或透明
5+App开发 状态栏 配置系统状态栏样式 iOS平台可支持对系统状态栏样式的配置,在应用manifest.json文件的plus->distribute->apple下添加UIStatu ...
- (转)code first基础
转自:http://tech.it168.com/a2011/0719/1220/000001220362_all.shtml [IT168 技术]随着.NET 4.0时代的到来,开发者越来越关注如何 ...