[PKUSC2018]星际穿越(倍增)
题意:n个点的图,点i和[l[i],i)的所有点连双向边。每次询问(l,r,x)表示x到[l,r]的所有点的最短路径长度和。
首先这题显然可以线段树优化建图,但是需要比较好的常数才能通过45分,还需要发掘性质。
先不考虑往右走的情况,对于一个点x,每个点i与x的最短距离一定形成一个个连续区间,即:设f[i][j]表示i走j步能到的最左的点,则$f[i][j+1]=\min\limits_{k=f[i][j]}^{i-1}l[k]$。所以只要往前扫一遍就能求出f[i]数组。
接着考虑往右走的情况,可以证明,一个点最多只需要往右走一次,所以只需要往后扫一遍就能求出新的f[i]数组。这样我们记录一个前缀和就可以在$O(n^2)$复杂度内解决问题。
可以发现f[i][j]这个数组显然是可以倍增优化的,直接套上RMQ类似的模板即可。
这里有一个简化代码的方法,就是f[i][j]改为表示[i..n]的所有点走$2^j$步之后能到达的最靠前的点,这样就可以直接倍增转移了。但是这样就要判断i最后是否需要先往右走一步,这里又有一个小技巧:先强制往左走一步,剩下的直接处理即可。
总码长不到1k。
#include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
typedef long long ll;
using namespace std; const int N=;
int n,Q,l,r,x,L[N],to[][N];
ll sm[][N]; int gcd(int a,int b){ return b ? gcd(b,a%b) : a; } ll calc(int l,int r){
if (L[r]<=l) return r-l;
ll ans=r-L[r]; r=L[r]; int tot=;
for (int i=; ~i; i--)
if (to[i][r]>l) ans+=sm[i][r]+tot*(r-to[i][r]),r=to[i][r],tot+=<<i;
return ans+(r-l)*(tot+);
} int main(){
freopen("pkua.in","r",stdin);
freopen("pkua.out","w",stdout);
scanf("%d",&n); L[]=;
rep(i,,n) scanf("%d",&L[i]);
to[][n]=L[n]; sm[][n]=n-L[n];
for (int i=n-; i; i--) to[][i]=min(to[][i+],L[i]),sm[][i]=i-to[][i];
rep(i,,) rep(j,,n) if (to[i-][j]){
to[i][j]=to[i-][to[i-][j]];
sm[i][j]=sm[i-][j]+sm[i-][to[i-][j]]+(to[i-][j]-to[i][j])*(1ll<<(i-));
}
for (scanf("%d",&Q); Q--; ){
scanf("%d%d%d",&l,&r,&x);
ll a=calc(l,x)-calc(r+,x),b=r-l+; int d=gcd(a%b,b);
printf("%lld/%lld\n",a/d,b/d);
}
return ;
}
[PKUSC2018]星际穿越(倍增)的更多相关文章
- [Luogu 5465] [LOJ 6435] [PKUSC2018]星际穿越(倍增)
[Luogu 5465] [LOJ 6435] [PKUSC2018]星际穿越(倍增) 题面 n个点的图,点i和[l[i],i)的所有点连双向边.每次询问(l,r,x)表示x到[l,r]的所有点的最短 ...
- LOJ.6435.[PKUSC2018]星际穿越(倍增)
LOJ BZOJ 参考这儿qwq. 首先询问都是求,向左走的最短路. \(f[i][j]\)表示从\(i\)走到\(j\)最少需要多少步.表示这样只会\(O(n^2\log n)\)的= =但是感觉能 ...
- [PKUSC2018]星际穿越
[PKUSC2018]星际穿越 题目大意: 有一排编号为\(1\sim n\)的\(n(n\le3\times10^5)\)个点,第\(i(i\ge 2)\)个点与\([l_i,i-1]\)之间所有点 ...
- LOJ #6435. 「PKUSC2018」星际穿越(倍增)
题面 LOJ#6435. 「PKUSC2018」星际穿越 题解 参考了 这位大佬的博客 这道题好恶心啊qwq~~ 首先一定要认真阅读题目 !! 注意 \(l_i<r_i<x_i\) 这个条 ...
- BZOJ5371[Pkusc2018]星际穿越——可持久化线段树+DP
题目描述 有n个星球,它们的编号是1到n,它们坐落在同一个星系内,这个星系可以抽象为一条数轴,每个星球都是数轴上的一个点, 特别地,编号为i的星球的坐标是i. 一开始,由于科技上的原因,这n个星球的居 ...
- 【洛谷5465】[PKUSC2018] 星际穿越(倍增)
点此看题面 大致题意: 给定\(l_{2\sim n}\),其中\(l_i\)表示\([l_i,i-1]\)的所有点与\(i\)之间存在一条长度为\(1\)的双向路径.每次询问给出\(l,r,x\), ...
- LOJ6435 PKUSC2018 星际穿越
这个题吧当时在考场只得了45分 然后70分的性质都分析到了 不知道为啥就是写萎蛋了 哎 当时还是too young too simple 看了一下julao们的博客这个题有两种做法 一个是比较费脑子的 ...
- 2019.03.09 bzoj5371: [Pkusc2018]星际穿越(主席树)
传送门 题意简述: 给一个序列,对于第iii个位置,它跟[limi,i−1][lim_i,i-1][limi,i−1]这些位置都存在一条长度为111的无向边. 称dist(u,v)dist(u,v) ...
- 题解 洛谷 P5465 【[PKUSC2018]星际穿越】
首先考虑题目的性质,发现点向区间连的边为双向边,所以也就可以从一个点向右跳到区间包含该点的点,如图所示: 但事实上向后跳其实是不优的,可以有更好的方法来节省花费: 因此我们发现一个点跳到其前一个区间的 ...
随机推荐
- java 11 完全支持Linux容器(包括Docker)
许多运行在Java虚拟机中的应用程序(包括Apache Spark和Kafka等数据服务以及传统的企业应用程序)都可以在Docker容器中运行.但是在Docker容器中运行Java应用程序一直存在一个 ...
- mongodb中比较级查询条件:($lt $lte $gt $gte)(大于、小于)、查找条件
查询表中学生年级大于20,如下: db.getCollection('student').find({'age':{'$gt':'20'}}) $lt < (less than ) ...
- 队列优化的dijkstra
#include<iostream> #include<queue> #include<cstdio> #include<cstring> #inclu ...
- Latex "Error: File ended while scanning use of \@xdblarge"
Latex 编译时出现 Error: File ended while scanning use of \@xdblarge" 是因为少了一个 }...
- MVC5 Entity Framework学习
MVC5 Entity Framework学习(1):创建Entity Framework数据模型 MVC5 Entity Framework学习(2):实现基本的CRUD功能 MVC5 Entity ...
- Leetcode#13. Roman to Integer(罗马数字转整数)
题目描述 罗马数字包含以下七种字符:I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II ,即 ...
- day 15 - 2 内置函数练习
内置函数练习 编写 sql 查询语句功能 文件内容: 1,Eva,22,13651054608,IT2,Vera,23,13304320533,Tearcher3,Renault,25,1333235 ...
- make: 警告:检测到时钟错误。您的创建可能是不完整的。
问题: make: 警告:检测到时钟错误.您的创建可能是不完整的. 原因:1. 文件时间不一致.(或者修改了系统时间) 如何解决:你touch *一下,然后重新编译 touch * touch命令有两 ...
- JdbcTemplate中queryForObject方法返回空结果或不正确结果数量的解决方法
在使用Spirng提供的JdbcTemplate中名为queryForObject API进行数据库查询时有时会抛出如下异常: org.springframework.dao.EmptyResultD ...
- Lua中的一些库(1)
[数学库] 数学库(math)由一组标准的数学函数构成.这里主要介绍几个常用的函数,其它的大家可以自行百度解决. 三角函数(sin,cos,tan……)所有的三角函数都使用弧度单位,可以用函数deg( ...