Portal -->CC_Children Trips

Solution

  (英文题解看得真爽qwq不过写的好详细啊ovo)

  首先这题有一个很重要的条件就是边权是\(1\)或者\(2\),所以虽然说我也不知道为什么这样就能突然想到了分块(是不是不知道怎么搞的时候就想分块啊qwq)

  我们按照学生的体力值是否大于\(\sqrt n\)将所有的询问分成两类,第一类是\(P<=\sqrt n\)的,第二类是\(P>\sqrt n\)的

​  我们首先来看\(P>\sqrt n\)的这类

​  如果说不考虑时间的话,我们有一种非常暴力的做法就是先预处理\(pre[i][j]\)数组用来倍增求\(lca\),然后再预处理一个\(dis[x]\)表示\(x\)这个节点到根的距离,有了这两个东西之后我们可以实现一个\(single\_jump(x,P)\),其中\(x\)表示开始往上跳的节点,\(P\)表示的是学生的体力值,这个过程的作用是在\(O(logn)\)的时间内求出\(x\)这个节点在体力限制为\(P\)的情况下,最远能够往上走到哪一个节点,也就是找到一个深度最浅的\(y\)满足\(dis[x]-dis[y]<=P\),并统计这个过程需要多少步

​  然后对于每次询问\((x,y,P)\)我们先求出\(lca\),然后分别从\(x\)和\(y\)两个节点开始\(single\_jump\)直到\(lca\),当然两边都可能有剩下的一小段,最后处理一下就好了(要么一步走完要么两步走完)

  这个是最暴力的一个想法,耗时的原因很简单,因为从\(x\)和\(y\)开始暴力\(single\_jump\),如果\(P\)很小那就很凉了,但是对于\(P>\sqrt n\)的情况下,最多跳的步数是\(\sqrt n\)级别的,所以总的复杂度就是\(O(\sqrt n logn)\),用来处理\(P>\sqrt n\)的情况问题不大ovo

  

​  接下来就是第一类\(P<=\sqrt n\)的情况了

​  显然我们要对”暴力\(single\_jump\)“这步进行优化,也就是要实现一次跳多步\(single\_jump\)

​  最套路的想法就是同样的我们可以预处理一个倍增数组\(up[i][j]\),表示从\(i\)开始往上进行\(1<<j\)次\(single\_jump\)最浅能跳到哪里,处理方法跟求\(lca\)的倍增数组类似,只要先\(O(nlogn)\)求出\(up[i][0]\)然后大力转移就好了,有了这个数组之后我们就可以直接用倍增的方式求要跳多少步可以跳到哪里了,其他部分保持不变

​  但是能预处理的前提是我们知道\(P\)是多少,现在的问题是每一个询问的\(P\)都是不同的

  也就是说每一次我们都要先\(O(nlogn)\)预处理一遍,这样显然是会爆炸的

  但是注意到,如果我们只用这个方法来处理\(P<=\sqrt n\)的情况,\(P\)的取值只有\(\sqrt n\)种,我们将第一类的所有询问按照\(P\)值从小到大排个序,那么最坏的预处理的总复杂度就是\(O(n^\frac{3}{2}logn)\),算一下好像有点爆炸然后我们来看一下时间是8sec那。。大概。。也许。。可以吧(实际上cc上面交了一发跑出来是。。4点多秒。。)

​  不过分块的事情是真的qwq不能信复杂度qwq毕竟是上界(比如某道回转寿司的题明明算出来炸得不行但是就是能过并且跑得飞快。。)

  

​  代码大概长这个样子

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=1e5+10,TOP=16;
struct xxx{int y,nxt,dis;
}a[N*2];
struct Data{int left_dis,step;Data(){}Data(int x,int y){left_dis=x; step=y;}
};
struct Rec{int x,y,P,id;Rec(){}Rec(int x1,int y1,int P1,int id1){x=x1; y=y1; P=P1; id=id1;}friend bool operator < (Rec x,Rec y){return x.P<y.P;}
}rec1[N],rec2[N];
int h[N],dep[N],dis[N],ans[N];
int pre[N][TOP+1],up[N][TOP+1];
int n,m,tot,rec1_cnt,rec2_cnt,sq,Cnt;
void add(int x,int y,int d){a[++tot].y=y; a[tot].nxt=h[x]; h[x]=tot; a[tot].dis=d;}
void dfs(int fa,int x,int d,int Dis){dis[x]=Dis; dep[x]=d;pre[x][0]=fa;for (int i=1;i<=TOP;++i) pre[x][i]=pre[pre[x][i-1]][i-1];int u;for (int i=h[x];i!=-1;i=a[i].nxt){u=a[i].y;if (u==fa) continue;dfs(x,u,d+1,Dis+a[i].dis);}
}
int get_lca(int x,int y){if (dep[x]<dep[y]) swap(x,y);for (int i=TOP;i>=0;--i)if (dep[pre[x][i]]>=dep[y]) x=pre[x][i];if (x==y) return x;for (int i=TOP;i>=0;--i)if (pre[x][i]!=pre[y][i]) x=pre[x][i],y=pre[y][i];return pre[x][0];
}
int single_jump(int x,int P){int now=dis[x];for (int i=TOP;i>=0;--i){if (now-dis[pre[x][i]]>P) continue;x=pre[x][i];}return x;
}
Data large_up(int x,int aim,int P){int tmp,left_dis=0,step=0;while (x!=aim){tmp=single_jump(x,P);if (dep[tmp]>dep[aim]){++step;x=tmp;}else{left_dis=dis[x]-dis[aim];break;}}return Data(left_dis,step);
}
Data small_up(int x,int aim,int P){int step=0;for (int i=TOP;i>=0;--i){if (dep[up[x][i]]>dep[aim])step+=1<<i,x=up[x][i];}return Data(dis[x]-dis[aim],step);
}
void solve(int x,int y,int P,int id){if (x==y){ans[id]=0;return;}int lca=get_lca(x,y);Data tmp1,tmp2;tmp1=P<=sq?small_up(x,lca,P):large_up(x,lca,P);tmp2=P<=sq?small_up(y,lca,P):large_up(y,lca,P);ans[id]=tmp1.step+tmp2.step;if (tmp1.left_dis+tmp2.left_dis<=P) ++ans[id];else ans[id]+=2;
}
void small_prework(int P){++Cnt;//for debug qwqfor (int i=1;i<=n;++i) up[i][0]=single_jump(i,P);for (int j=1;j<=TOP;++j)for (int i=1;i<=n;++i)up[i][j]=up[up[i][j-1]][j-1];
}
void Large(Rec *rec,int n){for (int i=1;i<=n;++i)solve(rec[i].x,rec[i].y,rec[i].P,rec[i].id);
}
void Small(Rec *rec,int n){sort(rec+1,rec+1+n);for (int i=1;i<=n;++i){if (i==1||rec[i].P!=rec[i-1].P)small_prework(rec[i].P);solve(rec[i].x,rec[i].y,rec[i].P,rec[i].id);}
}int main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);
#endifint x,y,d;scanf("%d",&n);sq=sqrt(n);memset(h,-1,sizeof(h));tot=0;for (int i=1;i<n;++i){scanf("%d%d%d",&x,&y,&d);add(x,y,d); add(y,x,d);}dfs(0,1,1,0);scanf("%d",&m);rec1_cnt=0; rec2_cnt=0;for (int i=1;i<=m;++i){scanf("%d%d%d",&x,&y,&d);if (d<=sq)rec1[++rec1_cnt]=Rec(x,y,d,i);elserec2[++rec2_cnt]=Rec(x,y,d,i);}Large(rec2,rec2_cnt);Small(rec1,rec1_cnt);for (int i=1;i<=m;++i) printf("%d\n",ans[i]);
}

转载于:https://www.cnblogs.com/yoyoball/p/9397857.html

【codechef】Children Trips相关推荐

  1. 【CODECHEF】Children Trips(分块)

    主要的操作是:每一天走到最远能够走到的休息区 确实一开始没有想到是分块,只是觉得1<=d<=21<=d<=21<=d<=2有点东西,但是没有搞出来. 其实也可以说是 ...

  2. 【CodeChef】【DP】Count Subsequences

    CodeChef CSUBSQ Count Subsequences 题目大意 ◇题目传送门◆ 如果一个整数序列的各元素之和可以被给定整数 KKK 整数,则称这个序列是好的.给定整数序列 A1,A2, ...

  3. Codechef :Children Trips/TRIPS(树分块)

    传送门 题解: 设一个阀值 k k k,小于 k k k的倍增,大于 k k k的暴力跳,这样的复杂度是 O ( n m k + n k ) O(\frac{nm}{k}+nk) O(knm​+nk) ...

  4. 【CodeChef】LCH15JGH Many bananas

    暴力可以水过. #include<bits/stdc++.h> using namespace std; char inc; inline void get(int& x) {x ...

  5. 【BZOJ3514】Codechef MARCH14 GERALD07加强版 LCT+主席树

    [BZOJ3514]Codechef MARCH14 GERALD07加强版 Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行 ...

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

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

  7. 一二三系列之CodeChef分块——Chef and Churu,Chef and Problems,Children Trips

    文章目录 Chef and Churu source solution code Chef and Problems source solution code Children Trips sourc ...

  8. [CodeChef Trips]Children Trips

    Children Trips 题解 关于这种跳跃的**题,当它PPP值很大时几次就可以跳到目标节点了,而较小时却会跳很久,所以我们很快就可以想到对询问分类处理. 对于P>nP>\sqrt{ ...

  9. Vue教程6【完结】【vue-router】路由,路由传参,编程式路由导航,缓存路由组件,路由守卫,路由模式,vue ui组件库

    vue-router 了解 vue插件库,用来实现SPA应用(单页面) 整个页面只有一个完整的页面 点击页面中导航链接,不会刷新页面,只做局部更新 数据通过ajax请求 路由的理解 一组映射关系(ke ...

最新文章

  1. 一套完整的3D结构光系统搭建指南!
  2. VisualSvn+TortoiseSVN的安装说明
  3. SDN协议与SD-WAN中使用的协议相比有何差别?
  4. 有梦想就有前进的动力
  5. php职业认证,如何用 PHP 进行 HTTP 认证
  6. python去重保留唯一一个值_Python DataFrame使用drop_duplicates()函数去重(保留重复值,取重复值)...
  7. wifi信号手机测试软件,专业的WiFi检测工具有哪些?如何解决wifi信号不好?
  8. java文件服务器_JavaWeb项目架构之NFS文件服务器
  9. ReportViewer教程(8)-对报表作一些调整(格式和属性)
  10. 编辑框CEdit自动换行简单设置
  11. android之socket编程实例
  12. Windows10更新工具
  13. visual studio 2015安装教程
  14. 云流送技术可以支持多人交互吗?
  15. JavaScript 数组和函数
  16. DELPHI7对日期格式的处理
  17. CentOS7 wifi安装配置问题总结
  18. arXiv镜像加载慢的解决办法
  19. idea如何配置或者创建mybatis的xml文件 idea如何配置或者创建mybatis的配置文件
  20. win7计算机c盘搜索不到,Win7系统如何查找C盘中的ProgramData文件夹?

热门文章

  1. 基于Java毕业设计校园外卖系统Web端源码+系统+mysql+lw文档+部署软件
  2. zsh与oh-my-zsh ← 阳志平的个人网站::技术 zsh与oh-my-zsh ← 阳志平的个人网站::技术...
  3. 111. Minimum Depth of Binary Tree
  4. 常用校验方式以及优缺点(奇偶校验,CRC校验,校验和)
  5. linux 搭建 gitlab 私人服务器
  6. Devops成功的八大炫酷工具
  7. 加权黑猩猩优化算法(WChOA)附Matlab代码
  8. python中iadd与add_如何为Python属性实现-uyu iadd_uu
  9. 上海财经大学计算机课程表,WakeUp课程表
  10. 一年赚上亿的生意_甩过梅艳芳,做生意一年赚几亿,他竟然火了快四十年