被 scb 神仙教育来扫荡北大营题目 Orz

Description

  https://loj.ac/problem/6435

Solution

  首先有个很显然的性质,就是对于一组询问 \(l,r,x\),从 \(x\) 到 \([l,r]\) 的最短距离 一定是从 \(x\) 一直向左走 或者从 \(x\) 向右走 \(1\) 单位时间然后一直向左走。

  向右走 \(1\) 单位时间到达的位置是 \(L_i\) 最小的 \(i\)。如果 \(\min\{L_i\}\ge L_x\) 那就不用考虑向右走一步的情况了,否则在 \(\min\{L_i\}\lt L_x\lt x\) 的限制下,我们可以从 \(x\) 一步到 \(i\)。

  然后 \(70\) 分做法就很显然了,从每个点出发,模拟上面两个情况即可。

  code (我之前把 \(q\) 也看成 \(5000\) 了,所以 T 了好几发)

  以上过程看起来可以倍增优化,然后就开始学习倍增转移技巧

  首先不分开考虑向右走和不向右走两种情况,我们在查询时先强制从 \(x\) 向左走一次,然后再往前倍增走即可,画图可知这样两种情况就合一了。此时我们不用考虑向右走的情况了,但强制往左走一次后再往左走到的位置 就要取位置 \([x,n]\) 中所有 \(L_i\) 的最小值,因为可能是从 \((x,n]\) 中某个位置走来的,即之前从 \(x\) 往右走了一步(如果 \(L_x\) 最小就无视这一步)。

  然后根据一开始说过的性质,最优答案最多只在一开始位于 \((x,n]\) 之间的位置,以后不会闲的蛋疼再回到那些位置,故一直顺带记录那些位置能到达的最左位置 不会影响找到最优解。

  这样代码就好实现了:预处理 \(to(i,j)\) 表示从 \([i,n]\) 中任一位置向左走 \(j\) 个单位时间,最左可以走到哪个位置;再预处理 \(sum(i,j)\) 表示从 \(i\) 到 \([to(i,j),i)\) 区间内所有位置的最短距离之和。

  查询时倍增跑到询问区间 \([l,r]\) 的左端点 \(l\) 即可。

  详见代码。

#include<bits/stdc++.h>
#define ll long long
#define N 300001
using namespace std;
inline int read(){
int x=0; bool f=1; char c=getchar();
for(;!isdigit(c); c=getchar()) if(c=='-') f=0;
for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+(c^'0');
if(f) return x;
return 0-x;
}
int n,q,L[N],to[20][N]; ll sum[20][N];
ll gcd(ll x, ll y){
ll t;
while(y) t=x, x=y, y=t%y;
return x;
}
ll calc(int l, int r){
if(L[r]<=l) return r-l;
ll ans=r-L[r]; r=L[r]; int tot=1;
for(int i=19; ~i; --i) if(to[i][r]>l) ans+=sum[i][r]+(ll)tot*(r-to[i][r]), r=to[i][r], tot+=1<<i;
return ans+(ll)(r-l)*(tot+1);
}
int main(){
n=read(); L[1]=1;
for(int i=2; i<=n; ++i) L[i]=read();
to[0][n]=L[n], sum[0][n]=n-L[n];
for(int i=n-1; i; --i) to[0][i]=min(to[0][i+1],L[i]), sum[0][i]=i-to[0][i];
for(int i=1; i<=19; ++i)
for(int j=1; j<=n; ++j)
to[i][j] = to[i-1][to[i-1][j]],
sum[i][j] = sum[i-1][j] + sum[i-1][to[i-1][j]] + (ll)(to[i-1][j]-to[i][j])*(1<<(i-1));
q=read(); int l,r,x;
while(q--){
l=read(), r=read(), x=read();
ll a=calc(l,x)-calc(r+1,x), b=r-l+1, g=gcd(a,b);
printf("%lld/%lld\n",a/g,b/g);
}
return 0;
}

【PKUSC2018】星际穿越的更多相关文章

  1. [PKUSC2018]星际穿越

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

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

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

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

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

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

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

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

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

  6. 2019.03.09 bzoj5371: [Pkusc2018]星际穿越(主席树)

    传送门 题意简述: 给一个序列,对于第iii个位置,它跟[limi,i−1][lim_i,i-1][limi​,i−1]这些位置都存在一条长度为111的无向边. 称dist(u,v)dist(u,v) ...

  7. 【洛谷5465】[PKUSC2018] 星际穿越(倍增)

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

  8. LOJ6435 PKUSC2018 星际穿越

    这个题吧当时在考场只得了45分 然后70分的性质都分析到了 不知道为啥就是写萎蛋了 哎 当时还是too young too simple 看了一下julao们的博客这个题有两种做法 一个是比较费脑子的 ...

  9. 题解 洛谷 P5465 【[PKUSC2018]星际穿越】

    首先考虑题目的性质,发现点向区间连的边为双向边,所以也就可以从一个点向右跳到区间包含该点的点,如图所示: 但事实上向后跳其实是不优的,可以有更好的方法来节省花费: 因此我们发现一个点跳到其前一个区间的 ...

  10. 「PKUSC2018」星际穿越 (70分做法)

    5371: [Pkusc2018]星际穿越 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 27  Solved: 11[Submit][Status] ...

随机推荐

  1. 《精通并发与Netty》学习笔记(05 - Google Protobuf与Netty的结合)

    protobuf是由Google开发的一套对数据结构进行序列化的方法,可用做通信协议,数据存储格式,等等.其特点是不限语言.不限平台.扩展性强 Netty也提供了对Protobuf的天然支持,我们今天 ...

  2. 华三F100系列防火墙 、华为USG6300系列防火 GRE 隧道配置

    GRE概述: 通用路由封装(GRE: Generic Routing Encapsulation)是通用路由封装协议,可以对某些网络层协议的数据报进行封装,使这些被封装的数据报能够在IPV4网络中传输 ...

  3. Hbase概述

    一.HBASE概述 Hadoop Database    NoSQL 面向列 提供实时更新查询 ....   是一个高可靠性 高性能 面向列 可伸缩的分布式存储系统 利用hbase技术可以在廉价的PC ...

  4. win7/xp解除系统限制的网速

    对电脑不熟悉者的方法: 1.单击“开始-开始搜索”,输入“gpedit.msc”,回车后即可打开“组策略对象编辑器”. 2.展开“计算机配置-管理模板-网络-QoS数据包计划程序”,双击右面设置栏中的 ...

  5. Django2.2 数据库的模块model学习笔记

    一.前言 为什么选用Django2.2,因为从2019年下半年起Django2.2逐渐成为长期支持版本,官网也有数据,所以当然选用维护时间长的版本 二.models的建立 Django的models也 ...

  6. windows 安装jenkins

    本文简单记录 windows 安装 jenkins. 1. 下载jenkins安装包,下载地址:https://jenkins.io/index.html 2. 选择下载windows版 3. 解压, ...

  7. Javascript - BOM 对象

    浏览器相关的对象.获取浏览器相关的信息,可以设置和修改浏览器属性. 0. web-app 版 TodoList 小程序 用以下内容可以自己手写一个 TodoList 小程序,再添加几行代码就可以用手机 ...

  8. Linux系列(5):入门之文件类型与扩展名

    通过本章你会了解到: 文件类型有哪些? 文件扩展名的意义是什么? 1.文件类型 任何设备在Linux系统中都是文件,不仅如此,连数据沟通的接口也有专属的文件在负责,所以Linux的文件种类真的很多,除 ...

  9. 用CTime类得到当前日期 时间

    (1)定义一个CTime类的对象CTime time: (2)得到当前时间time = CTime::GetCurrentTime(); (3)Get Year(),GetMonth(),GetDay ...

  10. PAT A1011 World Cup Betting(20)

    AC代码 #include <cstdio> #include <algorithm> const int max_n = 3; using namespace std; /* ...