基于观察,可以发现这样一条性质:

  • 我们并不关心当前位置和终点的绝对关系,只在乎当前位置和终点的距离,当这个距离确定的时候接下来能走到的位置也是确定的。

基于这个观察可以发现,本质上每个位置的状态就是和终点的距离。

进一步可以发现,对于一个查询 \(q = x\) 假设在 \(x - 1\) 已经到达了 \(p\) 位置,那么我们一定可以在 \(x\) 这个位置通过调整使得经过 \(x\) 后距离终点的距离为 \([0, p]\) 中任意一个数。

于是问题就转化为,是否存在 \([0, p]\) 中的一个距离 \(d\) 使得从 \(x + 1\) 开始往后走不能到达终点。

可以发现,对于前者从 \(1\) 走到 \(x - 1\) 后距离终点的距离是很好计算的。

直接令 \(f_i\) 表示 \(1\) 走到 \(i\) 后到终点的距离,则 \(f_i = \min(f_{i - 1}, |f_{i - 1} - a_i|)\)

重头戏在后面部分,如何求出对于每个起点距离终点 \(d\) 从 \(i\) 往后走能否到达终点呢?

同样考虑直接令 \(g_{i, j}\) 表示起点距离终点 \(j\),从 \(i\) 往后走能否走到终点。

那么就会有转移:

\[\begin{aligned}
g_{i, j} =
\begin{cases}
g_{i + 1, j} (a_i >= 2 \times j) \\
g_{i + 1, a_i - j} (j \le a_i < 2 \times j) \\
g_{i + 1, j - a_i} (a_i < j)
\end{cases}
\end{aligned}
\]

但是这样求是 \(O(nD)\) 的,显然不可取。

可以发现,问题在于我们不能计算出所有的距离 \(d\) 是否能到达。

于此同时又可以发现,我们并不需要知道所有的距离 \(d\) 是否能到达,只需要知道是否存在一个在 \([0, f_{i - 1}]\) 内的距离即可。

因此,为了尽可能满足在这个范围之内,我们只需要贪心地选取最小的哪个满足条件的距离,判断其是否在这个区间即可。

顺着这个思路考虑改写一下所求,令 \(g_i\) 表示最小的距离 \(d\) 使得 \(i\) 往后不能到达终点。

下面考虑转移,同样还是考虑分走或不走转移。

继续观察可以发现 \(\forall i, g_i \ge g_{i + 1}\),因此为了使得 \(g_i\) 最小应该尽量使得其不走动。

所以,当 \(a_i \ge 2 \times g_{i}\) 时,\(g_i = g_{i + 1}\),因为我们只知道 \(g_{i + 1}\),因此判定条件改为 \(a_i \ge 2 \times g_{i + 1}\)。

那么当 \(a_i < 2 \times g_{i + 1}\) 时,\(g_i \ge g_{i + 1} + a_i\);否则 \(g_i < g_{i + 1} + a_i \Rightarrow g_i - a_i < g_{i + 1}\) 同时 \(g_i - a_i\) 也是不合法的,与 \(g_{i + 1}\) 已经最小矛盾。

同时,这个下界显然是可以取到的,因此 \(g_i = g_{i + 1} + a_i(a_i < 2 \times g_{i + 1})\)

显然初始值 \(g_{n + 1} = 1\)。

最后查询直接判断是否 \(g_{q + 1} \le f_{q - 1}\) 即可,复杂度 \(O(n + q)\)。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i, l, r) for (int i = l; i <= r; ++i)
#define dep(i, l, r) for (int i = r; i >= l; --i)
const int N = 5e5 + 5;
const int inf = 1e9;
int n, q, D, x, a[N], f[N], g[N];
int read() {
char c; int x = 0, f = 1;
c = getchar();
while (c > '9' || c < '0') { if(c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
signed main() {
n = read(), D = read();
rep(i, 1, n) a[i] = read();
f[0] = D, g[n + 1] = 1;
rep(i, 1, n) f[i] = min(f[i - 1], abs(f[i - 1] - a[i]));
dep(i, 1, n) g[i] = (a[i] >= 2 * g[i + 1] ? g[i + 1] : g[i + 1] + a[i]);
q = read();
while (q--) x = read(), printf(g[x + 1] <= f[x - 1] ? "YES\n" : "NO\n");
return 0;
}

当要求某个范围内是否存在合法的数时,往往可以求某个特殊的合法的值,判断其是否在范围内即可。

比如 \([0, x]\) 内求最小,\([x, +\infty)\) 求最大。

AT2401 [ARC072C] Alice in linear land的更多相关文章

  1. [AT2401] [arc072_e] Alice in linear land

    题目链接 AtCoder:https://arc072.contest.atcoder.jp/tasks/arc072_c 洛谷:https://www.luogu.org/problemnew/sh ...

  2. ARC072E Alice in linear land

    ---题面--- 题解: 首先我们要观察到一个性质,因为在固定的起始距离下,经过固定的操作,最后所在的位置是固定的,我们设经过操作1 ~ i之后所在的地方距离终点为d[i]. 那么如果女巫可以修改第i ...

  3. 【ARC072E】Alice in linear land DP

    题目大意 有一个人要去直线上\(lm\)远处的地方,他会依次给他的机器发出\(n\)个指令.第\(i\)个指令为\(d_i\).他的机器收到一个指令\(x\)后,如果向目的地方向前进\(xm\)后比当 ...

  4. AtCoder Regular Contest 072 E:Alice in linear land

    题目传送门:https://arc072.contest.atcoder.jp/tasks/arc072_c 题目翻译 给你一个数组\(D\),然后给你一个操作序列\(d\),每次操作可以将\(D\) ...

  5. 【ARC072 E】Alice in linear land

    被智商题劝退,告辞 题意 有一个人在一条数轴的距离原点为 \(D\) 的位置,他可以执行 \(n\) 次操作,每次操作为给定一个整数 \(d_i\),这个人向原点的方向走 \(d_i\) 个单位,但如 ...

  6. 【ARC072E】Alice in linear land

    题目 瑟瑟发抖,这竟然只是个蓝题 题意大概就是初始在\(0\),要到坐标为\(D\)的地方去,有\(n\)条指令,第\(i\)条为\(d_i\).当收到一条指令\(x\)后,如果向\(D\)方向走\( ...

  7. 【arc072e】AtCoder Regular Contest 072 E - Alice in linear land

    题意 给定一个D,以及一个长度为N的序列a,顺序执行这些数字: 对于一个数字x,会使得D=min(D,abs(D-x)) 有Q次询问,每次询问独立,给出i,能否修改a[i],使得D最后不为0. n,q ...

  8. Atcoder Regular Contest 072 C - Alice in linear land(思维题)

    Atcoder 题面传送门 & 洛谷题面传送门 首先求出 \(s_i\) 表示经过 \(i\) 次操作后机器人会位于什么位置,显然 \(s_0=D\),\(s_i=\min(s_{i-1},| ...

  9. 【AtCoder】ARC072

    ARC072 C - Sequence 直接认为一个数是正的,或者第一个数是负的,每次将不合法的负数前缀和改成+1正数前缀和改成-1 #include <bits/stdc++.h> #d ...

随机推荐

  1. Codeforces 189A:Cut Ribbon(完全背包,DP)

    time limit per test : 1 second memory limit per test : 256 megabytes input : standard input output : ...

  2. Spring Boot实战二:集成Mybatis

    Spring Boot集成Mybatis非常简单,在之前搭建好的项目中加入Mybatis依赖的jar,在配置文件中加入数据库配置即可,如下图所示: 创建对应的Controller.Service.Da ...

  3. linux中网络存储与考试系统搭建(实现多用户可以共享文件)

    上期内容回顾 1.数据备份的方式有哪些 全量和增量 2.数据备份的命令有哪些 都有哪些优点缺点 cp : 本地复制,全量复制 scp : 远程复制,全量复制 rsync : 远程复制,增量复制 3.r ...

  4. Java+Eclipse+MySQL+Swing实现学生会考成绩管理系统(免费完整项目)

    版权声明:原创不易,本文禁止抄袭.转载,侵权必究! 目录 一.需求开发文档 二.数据库设计文档 三.功能模块部分代码及效果展示 四.完整源码下载 五.作者Info 一.需求开发文档 项目完整文件列表: ...

  5. Java中的构造方法「注意事项」

    构造方法是专门用来创建对象的方法,当我们通过关键字new来创建对象时,其实就是调用构造方法. 语法: public 类名称(参数类型 参数名称){ 方法体 } 注意事项: 构造方法的名称必须和所在的类 ...

  6. 编写Java程序,实现多线程操作同一个实例变量的操作会引发多线程并发的安全问题。

    查看本章节 查看作业目录 需求说明: 多线程操作同一个实例变量的操作会引发多线程并发的安全问题.现有 3 个线程代表 3 只猴子,对类中的一个整型变量 count(代表花的总数,共 20 朵花)进行操 ...

  7. MySQL8.0.20安装详解

    https://blog.csdn.net/yeb112233/article/details/106042867/ alter user root@localhost identified by ' ...

  8. 简单查看windows蓝屏原因

    相信各位在使用windows(xp.7.8.1.10...)过程中都遇到过蓝屏的情况,而蓝屏时,系统会将其记录起来,并追踪到引起蓝屏的程序,以下内容将简单介绍一下如何查看引起windows蓝屏的原因: ...

  9. Oracle 报 ORA-00054资源正忙的解决办法

    oracle之报错:ORA-00054: 资源正忙,要求指定 NOWAIT 问题如下: SQL> conn scott/tiger@vm_database Connected to Oracle ...

  10. centos 内存使用情况+负载使用情况

    内存使用情况,查看内存 free -h #查看内存 available:  可用内存 buff/cache:   缓存内存 free:   空闲内存 used: 已使用内存 负载使用情况 cat /p ...