[LOJ 6435][PKUSC 2018]星际穿越
[LOJ 6435][PKUSC 2018]星际穿越
题意
给定 \(n\) 个点, 每个点与 \([l_i,i-1]\) 之间的点建立有单位距离的双向边. \(q\) 组询问从 \(x\) 走到 \([l,r]\) 中的随机一点的期望距离. 输出既约分数.
\(n,q\le 3\times 10^5\), \(l<r<x\).
题解
显然对于一个 \(k\), \(k\) 步之内能到达的点是 \([1,x)\) 的一个后缀. 那么也就是说 \([1,x)\) 中的点的答案被分成了若干段, 每段的答案相同且向前递增.
手动模拟一下, 我们发现第一步可以走到的左端点是 \(l_x\), 第二步可以走到的就是 \(\min\limits_{k\ge l_x}l_k\) 了. 原因是所有可能一步到达 \(\min\limits_{k\ge l_x}l_k\) 的点都必然可以被 \(x\) 一步到达(如果 \(l_k\) 在 \(k>x\) 处取得最小值, 那么显然 \(l_k<x\). 又由于 \(k\) 连接的是 \([l_k,k)\), 那么必然和 \(x\) 直接相连). 且后面的步骤都是形如 \(l_k\) 的后缀 \(\min\) 的形式.
于是我们可以在第二步及以后尝试倍增.
倍增的同时不仅记录到达的左端点, 同时记录一下倍增时跳过的点的距离总和. 这样就可以在 \(O(\log n)\) 的时间内计算出 \(x\) 到 \([l,x)\) 内的所有点的最短路之和了. 两个后缀和相减即可得到 \([l,r]\) 内的答案.
最后约分一下输出就完了. 虽然最终答案是 \(O(n^2)\) 级别的但是数据比较弱并没有爆 int...
参考代码
#include <bits/stdc++.h>
const int MAXN=3e5+10;
int n;
int q;
int l[MAXN];
int lg[MAXN];
int sum[20][MAXN];
int prev[20][MAXN];
int* minl=prev[0];
int ReadInt();
int Calc(int,int);
int main(){
	n=ReadInt();
	for(int i=2;i<=n;i++)
		l[i]=ReadInt();
	q=ReadInt();
	l[1]=1;
	minl[n+1]=n;
	for(int i=n;i>=1;i--){
		minl[i]=std::min(l[i],minl[i+1]);
		sum[0][i]=i-minl[i];
	}
	for(int i=1;i<=n;i++)
		sum[0][i]=i-minl[i];
	for(int i=1;(1<<i)<=n;i++){
		lg[1<<i]=1;
		for(int j=1;j<=n;j++){
			prev[i][j]=prev[i-1][prev[i-1][j]];
			sum[i][j]=sum[i-1][j]+sum[i-1][prev[i-1][j]]+((prev[i-1][j]-prev[i][j])<<(i-1));
		}
	}
	for(int i=1;i<=n;i++)
		lg[i]+=lg[i-1];
	for(int i=0;i<q;i++){
		int l=ReadInt(),r=ReadInt(),pos=ReadInt();
		int a=Calc(pos,l)-Calc(pos,r+1);
		int b=r-l+1;
		int gcd=std::__gcd(a,b);
		printf("%d/%d\n",a/gcd,b/gcd);
	}
	return 0;
}
int Calc(int pos,int lim){
	if(l[pos]<lim)
		return pos-lim;
	int dis=0,p=l[pos],ans=pos-lim;
//	printf("x %d %d\n",ans,p);
	for(int i=lg[p];i>=0;i--){
		if(lim<=prev[i][p]){
			ans+=sum[i][p]+(p-prev[i][p])*dis;
//			printf("$ %d Q(%d,%d) %d\n",i,pos,lim,ans);
			p=prev[i][p];
			dis|=(1<<i);
		}
	}
	return ans+(p-lim)*(dis+1);
}
inline int ReadInt(){
	int x=0;
	register char ch=getchar();
	while(!isdigit(ch))
		ch=getchar();
	while(isdigit(ch)){
		x=x*10+ch-'0';
		ch=getchar();
	}
	return x;
}

[LOJ 6435][PKUSC 2018]星际穿越的更多相关文章
- [LOJ 6433][PKUSC 2018]最大前缀和
		[LOJ 6433][PKUSC 2018]最大前缀和 题意 给定一个长度为 \(n\) 的序列, 求把这个序列随机打乱后的最大前缀和的期望乘以 \(n!\) 后对 \(998244353\) 取膜后 ... 
- [LOJ 6432][PKUSC 2018]真实排名
		[LOJ 6432][PKUSC 2018]真实排名 题意 给定 \(n\) 个选手的成绩, 选中其中 \(k\) 个使他们的成绩翻倍. 对于每个选手回答有多少种方案使得他的排名不发生变化. \(n\ ... 
- LOJ #6435. 「PKUSC2018」星际穿越(倍增)
		题面 LOJ#6435. 「PKUSC2018」星际穿越 题解 参考了 这位大佬的博客 这道题好恶心啊qwq~~ 首先一定要认真阅读题目 !! 注意 \(l_i<r_i<x_i\) 这个条 ... 
- [Luogu 5465] [LOJ 6435] [PKUSC2018]星际穿越(倍增)
		[Luogu 5465] [LOJ 6435] [PKUSC2018]星际穿越(倍增) 题面 n个点的图,点i和[l[i],i)的所有点连双向边.每次询问(l,r,x)表示x到[l,r]的所有点的最短 ... 
- PKUSC 2018 题解
		PKUSC 2018 题解 Day 1 T1 真实排名 Link Solution 考虑对于每一个人单独算 每一个人有两种情况,翻倍和不翻倍,他的名次不变等价于大于等于他的人数不变 设当前考虑的人的成 ... 
- 「PKUSC2018」星际穿越  (70分做法)
		5371: [Pkusc2018]星际穿越 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 27 Solved: 11[Submit][Status] ... 
- [PKUSC2018]星际穿越
		[PKUSC2018]星际穿越 题目大意: 有一排编号为\(1\sim n\)的\(n(n\le3\times10^5)\)个点,第\(i(i\ge 2)\)个点与\([l_i,i-1]\)之间所有点 ... 
- BZOJ5371[Pkusc2018]星际穿越——可持久化线段树+DP
		题目描述 有n个星球,它们的编号是1到n,它们坐落在同一个星系内,这个星系可以抽象为一条数轴,每个星球都是数轴上的一个点, 特别地,编号为i的星球的坐标是i. 一开始,由于科技上的原因,这n个星球的居 ... 
- (纪录片)《星际穿越》中的科学 The Science of Interstellar
		简介: 导演: Gail Willumsen编剧: Gail Willumsen主演: 克里斯托弗·诺兰 / 乔纳森·诺兰 / 基普·索恩 / 马修·麦康纳类型: 纪录片 / 短片制片国家/地区: 美 ... 
随机推荐
- python持久化对象
			通过shelve模块即可持久化对象 代码 import shelve import numpy as np def writeObj(name,obj): with shelve.open('obje ... 
- Python进阶小结
			目录 一.异常TODO 二.深浅拷贝 2.1 拷贝 2.2 浅拷贝 2.3 深拷贝 三.数据类型内置方法 3.1 数字类型内置方法 3.1.1 整型 3.1.2 浮点型 3.2 字符串类型内置方法 3 ... 
- 《Effective-Ruby》读书笔记
			本篇是在我接触了 Ruby 很短一段时间后有幸捧起的一本书,下面结合自己的一些思考,来输出一下自己的读书笔记 前言 学习一门新的编程语言通常需要经过两个阶段: 第一个阶段是学习这门编程语言的语法和结构 ... 
- C语言程序设计100例之(3): Cantor表
			例3 Cantor表 题目描述 现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的.他是用下面这一张表来证明这一命题的: 1/1 1/2 1/3 1/4 …… 2/1 ... 
- Web前端——JavaScript笔记
			js 数据类型 字符串可以使用''或者是"" 运算符 == 只比较内容 === 比较内容,也比较类型是否一样,两个为true才为true !== 与上面===相反 var a=12 ... 
- 使用dapper遇到的问题及解决方法
			在使用dapper进行数据查询时遇到的一个问题,今天进行问题重现做一个记录,免得忘记以后又犯同样的错误. 自己要实现的是:select * from tablename where id in(1,2 ... 
- SSM(七)在JavaWeb应用中使用Redis
			前言 先来看一张效果图: 作用就是在每次查询接口的时候首先判断Redis中是否有缓存,有的话就读取,没有就查询数据库并保存到Redis中,下次再查询的话就会直接从缓存中读取了.Redis中的结果:之后 ... 
- JDK1.8新特性——Collector接口和Collectors工具类
			JDK1.8新特性——Collector接口和Collectors工具类 摘要:本文主要学习了在Java1.8中新增的Collector接口和Collectors工具类,以及使用它们在处理集合时的改进 ... 
- Java生鲜电商平台-商城后台架构与原型图实战
			Java生鲜电商平台-商城后台架构与原型图实战 说明:生鲜电商平台的运营平台,其中需要很多的功能进行管理.目前把架构与原型图实战分享给大家,希望对大家有用. 仪表盘/首页,简单统计,报表页,运营快捷口 ... 
- PHP面试题2019年小米工程师面试题及答案解析
			一.单选题(共29题,每题5分) 1.PHP面向对象方法重写描述错误的是? A.子类必须继承父类 B.子类可以重写父类已有方法 C.重写之后子类会调用父类方法 D.子类也可以具有与父类同名的属性,进行 ... 
