ARC072E Alice in linear land

~~~题面~~~

题解:

  首先我们要观察到一个性质,因为在固定的起始距离下,经过固定的操作,最后所在的位置是固定的,我们设经过操作1 ~ i之后所在的地方距离终点为d[i].

  那么如果女巫可以修改第i个操作,那么就相当于已经经过了1 ~ i - 1的操作,所以这个时候Alice已经在d[i - 1]的位置了,那么这个时候女巫可以通过修改s[i]来使得Alice和终点的距离减小,因为如果一个s[i]可以使得距离缩小,那么Alice一定会走,因此Alice的下一位置将是[0, d[i - 1]]中的任意位置。

  我们设f[i]表示最小的起始距离x使得经过i ~ n的操作无法到达终点。

  那么显然如果f[i + 1] <= d[i - 1],女巫就一定可以使得Alice无法到达终点。

  因此考虑如何转移。

  首先f[n + 1]表示不经过任何操作,那么这个时候的最小距离显然是1.

  考虑加入一个操作s[i]。

  1,如果当前在f[i + 1] 并且 s[i]这个操作不会被执行,那么s[i]就不会对f[i]造成影响,所以最近的距离还是f[i + 1]。

  那么什么时候s[i]不会被执行?显然s[i]需要 >= f[i  + 1]并使得s[i] - f[i + 1] >= f[i + 1],移项得到f[i + 1] <= s[i] / 2.

  2,如果这个操作被执行,那么将会缩短与目的地的距离,因为经过f[i + 1]的操作,最小的无法到达目的地的距离为f[i + 1],

  而原本在f[i + 1]的Alice经过s[i]这个操作缩短了与目的地的距离后,距离已经小于f[i + 1]了,因此这个时候肯定是可以到达目的地了。

  而为了使f[i]尽可能小,所以肯定要使得f[i]经过操作s[i]后到达f[i + 1],因为f[i + 1]是经过操作i + 1 ~ n最小的无法到达目的地的距离,不能再更小了。

  因此f[i] = f[i + 1] + s[i].

  

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define R register int
 4 #define AC 501000
 5 #define LL long long
 6 
 7 int n, m;
 8 int s[AC], d[AC], f[AC];
 9 
10 inline int read()
11 {
12     int x = 0;char c = getchar();
13     while(c > '9' || c < '0') c = getchar();
14     while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
15     return x;
16 }
17 
18 void pre()
19 {
20     n = read(), d[0] = read();
21     for(R i = 1; i <= n; i ++) 
22     {
23         s[i] = read(), d[i] = d[i - 1];
24         if(d[i] >= s[i]) d[i] -= s[i]; 
25         else if(s[i] - d[i] < d[i]) d[i] = s[i] - d[i];
26     }
27 }
28 
29 void work()//f[i]表示经过操作i ~ n,使得Alice无法到达终点的最小起始距离x
30 {
31     f[n + 1] = 1;
32     for(R i = n; i; i --)
33         if(f[i + 1] <= s[i] / 2) f[i] = f[i + 1];
34         else f[i] = f[i + 1] + s[i];
35     m = read();
36     for(R i = 1; i <= m; i ++)
37     {
38         int x = read();
39         if(d[x - 1] >= f[x + 1]) printf("YES\n");
40         else printf("NO\n");
41     }    
42 }
43 
44 int main()
45 {
46     freopen("in.in", "r", stdin);
47     pre();
48     work();
49     fclose(stdin);
50     return 0;
51 }
View Code

 

转载于:https://www.cnblogs.com/ww3113306/p/9873499.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值