← 回到所有文章

AT_arc072_c [ARC072E] Alice in linear land 题解

题意 有一个数轴,终点为原点。一个机器人位于 D,有 n 条指令,对第 i 条指令机器人会向终点移动 di 距离,若移动后距离变大则不移动,意思是可能冲过,但是若距离变小就可以过去。 给出 m 个询问…

题解文章的简约插画封面

题意

有一个数轴,终点为原点。一个机器人位于 DD,有 nn 条指令,对第 ii 条指令机器人会向终点移动 did_i 距离,若移动后距离变大则不移动,意思是可能冲过,但是若距离变小就可以过去。

给出 mm 个询问,第 ii 次询问允许将 dqid_{q_i} 修改为任意整数(仅当前询问生效)。问是否存在修改方案使机器人不能走到终点。

题解

记 disidis_i 表示不修改前 ii 个操作情况下,当前能走动哪。那么对于一次可以修改 dxd_x 的询问,若存在一个 y≤dx−1y\leq d_{x-1} 使得 yy 在经过 i+1i+1 到 nn 的操作后没到 00 则有解,否则无解。所以考虑求出最小使得走完后面操作不为 00 的距离,记 mnimn_i 表示最小走完 ii 到 nn 的操作之后不为 00 的距离,倒着 dp 即可:

  1. 当 mni+1≤di2mn_{i+1}\leq\frac{d_i}{2},有 mni=mni+1mn_i=mn_{i+1}。因为这种情况肯定会直接冲过,但是冲过 di−mni+1≥mni+1d_i-mn_{i+1}\geq mn{i+1} 故不会这样走,这样 mnimn_i 取到了下限。
  2. 当 mni+1>di2mn_{i+1}\gt\frac{d_i}{2},有 mni=mni+1+dimn_i=mn_{i+1}+d_i。分类讨论一下,若这一步是冲过的,那么 mi=di−mni+1<mni+1m_i=d_i-mn_{i+1}\lt mn_{i+1} 所以不可能;若没动,那么 mni=mni+1mn_i=mn_{i+1} 这时候若直接冲过 di−mni+1<mni+1d_i-mn_{i+1}\lt mn_{i+1} 不可能,或者直接走过去 mni+1−di+1<mni+1mn_{i+1}-d_{i+1}\lt mn_{i+1} 所以也不可能;所以只能是直接走过去的情况。
#include<bits/stdc++.h>
// #define ONLINE_JUDGE
#define INPUT_DATA_TYPE int
#define OUTPUT_DATA_TYPE int
inline __attribute((always_inline)) INPUT_DATA_TYPE read(){register INPUT_DATA_TYPE x=0;register char f=0,c=getchar();while(c<'0'||'9'<c)f=(c=='-'),c=getchar();while('0'<=c&&c<='9')x=(x<<3)+(x<<1)+(c&15),c=getchar();return f?-x:x;}void print(OUTPUT_DATA_TYPE x){if(x<0)x=-x,putchar('-');if(x>9)print(x/10);putchar(x%10^48);return;}

int mnD[500010],dis[500010],d[500010];

int abss(int x){return x<0?-x:x;}

int main(){
	#ifndef ONLINE_JUDGE
	freopen("name.in", "r", stdin);
	freopen("name.out", "w", stdout);
	#endif

    register int i;
    int n=read();
    dis[0]=read();
    for(i=1;i<=n;++i){
        d[i]=read();
        dis[i]=std::min(abss(dis[i-1]-d[i]),dis[i-1]);
    }
    mnD[n+1]=1;
    for(i=n;i;--i){
        if(d[i]/2>=mnD[i+1]) mnD[i]=mnD[i+1];
        else mnD[i]=mnD[i+1]+d[i];
    }

    int q=read();
    while(q--){
        i=read();
        puts(dis[i-1]>=mnD[i+1]?"YES":"NO");
    }

	#ifndef ONLINE_JUDGE
	fclose(stdin);
	fclose(stdout);
	#endif
    return 0;
}

谢谢你,读到这里。

本文同步自洛谷专栏,保留原始正文与发布时间。在洛谷查看原文 ↗

搜索文章

输入关键词,发现一些值得阅读的文字。

探索文字里的小小世界esc 关闭