点此看题面

大致题意: 给定\(l_{2\sim n}\),其中\(l_i\)表示\([l_i,i-1]\)的所有点与\(i\)之间存在一条长度为\(1\)的双向路径。每次询问给出\(l,r,x\),求\(\frac 1{r-l+1}\sum_{y=l}^{r}dist(x,y)\)。

重要性质

首先我们需要知道,这道题关键在于如何求出任意两点间的距离。

一个简单的性质,从\(i\)出发,如果你能通过\(t\)步到达\(x\),则必然能到达满足\(x\le y\le i\)的任意\(y\)。

而现在我们来考虑一个重要的问题,即:从点\(i\)出发,经过一步,能到达哪些点?

首先,\([l_i,i-1]\)显然是能够到达的。

然后呢?再仔细去研究一下,便会发现题目中提到路径是双向的,所以对于那些\(l_x\le i\)且\(x>i\)的\(x\),也是能够到达的。

那么,从点\(i\)出发,经过两步,能到达的编号最小的点是什么呢?

这自然就是所有\(i\)经过一步能到达的点所能一步到达的编号最小的点中编号最小的了,即:

\[\min_{k=l_i}^nl_k
\]

注意,之所以这里枚举的范围可以是\(l_i\sim n\),是因为这一范围中除去符合条件(即能够一步到达)的点以外都是\(l_x>i\)的点,这些点自然无法对答案造成贡献,因此枚举在内并无影响。

继续下去,从点\(i\)出发,经过三步,能到达的编号最小的点是什么呢?

很显然,如果设经过\(x\)步能到达的编号最小的点为\(p_x\),那么:

\[p_3=\min_{k=p_2}^nl_k
\]

推广可知:

\[p_x=\min_{k=p_{x-1}}^nl_k
\]

然后我们就可以发现,除去第一步能到达的点比较特殊以外,其余时候能到达的点都有一定规律。

实际上,在已确定当前能到达的编号最小的点的情况下,下一步能到达的编号最小的点是唯一确定的。

于是乎,我们就能想到倍增。

倍增

首先我们特殊处理第一步,因为它比较特殊。

接下来,我们设\(f_{x,y}\)表示\(x\)再走\(2^y\)步所能到达的编号最小的点,并用\(g_{x,y}\)表示\([f_{x,y},x-1]\)范围内所有点到\(x\)的距离之和。

\(f\)的预处理,显然就是传统的\(f_{x,y}=f_{f_{x,y-1},y-1}\),而\(g\)的预处理就要略显复杂。

首先,\([f_{x,y-1},x-1]\)到\(x\)的路径总和\(g_{x,y-1}\)与\([f_{x,y},f_{x,y-1}-1]\)到\(f_{x,y-1}\)的路径总和\(g_{f_{x,y-1},y-1}\)显然都是要计算在内的。

而\([f_{x,y},f_{x,y-1}-1]\)内的点从\(f_{x,y-1}\)到\(x\)的距离都要另行计算,而这一距离实际上就是\(2^{y-1}\)。

又因为要计算这一距离的点共有\(f_{x,y-1}-f_{x,y}\)个,所以\(g_{x,y}=g_{x,y-1}+g_{f_{x,y-1},y-1}+(f_{x,y-1}-f_{x,y})\times 2^{y-1}\)。

如果定义一个函数\(Jump(x,y)\),其值为\([y,x-1]\)范围内所有点到\(x\)的距离之和,则有:

\[\sum_{y=l}^{r}dist(x,y)=Jump_(x,l)-Jump(x,r+1)
\]

也就是说,实现\(Jump(x,y)\)之后,我们就可以差分计算出答案了。

而\(Jump(x,y)\)的实现,就可以利用上面的倍增数组。

先特殊处理第一步,初始化答案为\(x-l_x\)(实际上就是\(1\times(x-l_x)\))。然后更新\(x\)为\(l_x\)(因为这一部分的答案已经计算过了),并初始化\(k=1\)(表示接下来所有点到初始\(x\)的距离都需要加上\(1\)),接下来从大到小枚举\(i\)表示前进\(2^i\)步。

对于\([f_{x,i},x-1]\)到现在\(x\)的距离,就是\(g_{x,i}\),而其到初始\(x\)的距离还要加上\(k\),由于共有\(x-f_{x,i}\)个点,因此也就是加上\(k(x-f_{x,i})\)。然后我们更新\(x\)为\(f_{x,i}\),并将\(k\)加上\(2^i\)。

重复此流程,即可。

注意最后还要求一次剩余点到\(x\)的距离,因为并不是所有点都恰好是\(f\)的,以保证处理完毕。

具体实现详见代码。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 300000
#define LN 20
#define LL long long
using namespace std;
int n,a[N+5],f[N+5][LN+5];LL g[N+5][LN+5];
class FastIO
{
private:
#define FS 100000
#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
#define pc(c) (C==E&&(clear(),0),*C++=c)
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
int T;char c,*A,*B,*C,*E,FI[FS],FO[FS],S[FS];
public:
I FastIO() {A=B=FI,C=FO,E=FO+FS;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
Tp I void write(Ty x) {W(S[++T]=x%10+48,x/=10);W(T) pc(S[T--]);}
Tp I void write(Con Ty& x,Con char& y) {write(x),pc(y);}
I void clear() {fwrite(FO,1,C-FO,stdout),C=FO;}
}F;
I LL Jump(RI x,CI y)//倍增求答案
{
if(y>=a[x]) return x-y;LL t=x-a[x],k=1;x=a[x];//特殊处理第一步
for(RI i=LN;~i;--i) y<=f[x][i]&&(t+=k*(x-f[x][i])+g[x][i],k+=1<<i,x=f[x][i]);//重复执行中间过程
return t+=k*(x-y)+(x-y);//最后保证处理完毕
}
I LL gcd(Con LL& x,Con LL& y) {return y?gcd(y,x%y):x;}//求最大公约数,用于约分
int main()
{
RI Qt,i,j,x,y,z;LL t,d;for(F.read(n),i=2;i<=n;++i) F.read(a[i]);//读入数据
for(f[n][0]=a[n],g[n][0]=n-a[n],i=n-1;i;--i) f[i][0]=min(a[i],f[i+1][0]),g[i][0]=i-f[i][0];//初始化f和g
for(j=1;j<=LN;++j) for(i=1;i<=n;++i) f[i][j]=f[f[i][j-1]][j-1],//倍增打表f
g[i][j]=g[i][j-1]+g[f[i][j-1]][j-1]+((1LL*f[i][j-1]-f[i][j])<<j-1);//倍增打表g
F.read(Qt);W(Qt--) F.read(x),F.read(y),F.read(z),//处理询问
t=Jump(z,x)-Jump(z,y+1),d=gcd(t,y-x+1),F.write(t/d,'/'),F.write((y-x+1)/d,'\n');//差分
return F.clear(),0;
}

【洛谷5465】[PKUSC2018] 星际穿越(倍增)的更多相关文章

  1. [Luogu 5465] [LOJ 6435] [PKUSC2018]星际穿越(倍增)

    [Luogu 5465] [LOJ 6435] [PKUSC2018]星际穿越(倍增) 题面 n个点的图,点i和[l[i],i)的所有点连双向边.每次询问(l,r,x)表示x到[l,r]的所有点的最短 ...

  2. LOJ.6435.[PKUSC2018]星际穿越(倍增)

    LOJ BZOJ 参考这儿qwq. 首先询问都是求,向左走的最短路. \(f[i][j]\)表示从\(i\)走到\(j\)最少需要多少步.表示这样只会\(O(n^2\log n)\)的= =但是感觉能 ...

  3. [PKUSC2018]星际穿越(倍增)

    题意:n个点的图,点i和[l[i],i)的所有点连双向边.每次询问(l,r,x)表示x到[l,r]的所有点的最短路径长度和. 首先这题显然可以线段树优化建图,但是需要比较好的常数才能通过45分,还需要 ...

  4. [PKUSC2018]星际穿越

    [PKUSC2018]星际穿越 题目大意: 有一排编号为\(1\sim n\)的\(n(n\le3\times10^5)\)个点,第\(i(i\ge 2)\)个点与\([l_i,i-1]\)之间所有点 ...

  5. 最小生成树+LCA【洛谷 P2245】 星际导航

    [洛谷 P2245] 星际导航 题目描述 sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好.为了方便起见,我们可以认为宇宙是一张有N 个顶点和M 条边 ...

  6. 洛谷P3324 [SDOI2015]星际战争

    题目:洛谷P3324 [SDOI2015]星际战争 思路: 类似<导弹防御塔>,因为题目保证有解,花费时间小于最终答案时一定无法消灭所有敌人,只要花费时间大于等于最终答案都可以消灭所有敌人 ...

  7. LOJ #6435. 「PKUSC2018」星际穿越(倍增)

    题面 LOJ#6435. 「PKUSC2018」星际穿越 题解 参考了 这位大佬的博客 这道题好恶心啊qwq~~ 首先一定要认真阅读题目 !! 注意 \(l_i<r_i<x_i\) 这个条 ...

  8. 洛谷 P2317 [HNOI2005]星际贸易 解题报告

    P2317 [HNOI2005]星际贸易 题目描述 输入输出格式 输入格式: 输出格式: 如果可以找到这样的方案,那么输出文件output.txt中包含两个整数X和Y.X表示贸易额,Y表示净利润并且两 ...

  9. BZOJ5371[Pkusc2018]星际穿越——可持久化线段树+DP

    题目描述 有n个星球,它们的编号是1到n,它们坐落在同一个星系内,这个星系可以抽象为一条数轴,每个星球都是数轴上的一个点, 特别地,编号为i的星球的坐标是i. 一开始,由于科技上的原因,这n个星球的居 ...

随机推荐

  1. delphi使用Foxit Quick PDF Library读写pdf文本和图片

    简介: Debenu Quick PDF Library(PDF编程开发工具)提供一套全方位的 PDF API 函数,帮助您快速简便地处理 PDF 文件.从文档属性的基本操作到创建您自己的 PDF 查 ...

  2. Electron npm install 常见错误(Windows)

    问题一:node_gyp使用版本不对 if not defined npm_config_node_gyp (node "C:\Users\Administrator\AppData\Roa ...

  3. 数据库三,exec内置函数

    数据库三,exec内置函数 一.数据库查询与执行顺序 必备知识 查询语句的基本操作 - select - from - where - group by - having - distinct - o ...

  4. log file sync等待超高案例浅析

    监控工具DPA发现海外一台Oracle数据库服务器DB Commit Time指标告警,超过红色告警线(40毫秒左右,黄色告警是10毫秒,红色告警线是20毫秒),如下截图所示,生成了对应的时段的AWR ...

  5. TICK技术栈(五)Kapacitor安装及使用

    1.什么是Kapacitor? Kapacitor是InfluxData开源的数据处理引擎.它可以处理来自InfluxDB的流数据和批处理数据,并且用户可以用tickScript脚本来处理,监视和警报 ...

  6. 12C新功能:在线移动数据文件 (Doc ID 1566797.1)

    12C New Feature : Move a Datafile Online (Doc ID 1566797.1) APPLIES TO: Oracle Database - Enterprise ...

  7. 以太网驱动的流程浅析(三)-ifconfig的-19错误最底层分析【原创】

    以太网驱动流程浅析(三)-ifconfig的-19错误最底层分析 Author:张昺华 Email:920052390@qq.com Time:2019年3月23日星期六 此文也在我的个人公众号以及& ...

  8. Linux系统学习 十、DHCP服务器—介绍和原理

    介绍: DHCP服务作用(动态主机配置协议) 为大量客户机自动分配地址.提供几种管理 减轻管理和维护成本.提高网络配置效率 可分配的地址信息主要包括: 网卡的IP地址.子网掩码 对应的网路地址.广播地 ...

  9. [译]Vulkan教程(03)开发环境

    [译]Vulkan教程(03)开发环境 这是我翻译(https://vulkan-tutorial.com)上的Vulkan教程的第3篇. In this chapter we'll set up y ...

  10. java之操作集合的工具类--Collections

    Collections是一个操作Set.List和Map等集合的工具类. Collections中提供了大量方法对集合元素进行排序.查询和修改等操作,还提供了对集合对象设置不可变.对集合对象实现同步控 ...