传送门

题目大意

坐标轴上有$n$个坐标,第$i$个坐标是$x_i$,初始你有一个容量$V$,当两个给定的坐标距离不超过$V$时,你可以从一个坐标到达另一个坐标,同时你还可以令$V=\lfloor \frac{V}{2}\rfloor$,并到达一个任意一个给定的坐标。

求对于每一个点是否存在一种方案使得从这个点出法能够到达每一个点至少一次。

题解

首先$V$的值只有$\log V$种,对于每一种取值,会有若干段下标连续的坐标可以互相到达,要求在每一层取一段使得所有坐标都被覆盖,题意即为在强制选第一层的某一段,是否存在合法方案。

考虑先预处理每一层每一个坐标能到达的最左和最右的坐标,再在忽略第一层的意义下将每一层是否被选中的状态压缩起来,求出用了某些层所能覆盖的最长前缀和后缀。

设某一选中的状态集合为$K$,全集为$S$,$K$所能覆盖的最长前缀为$Pre_K$,最长后缀为$Suf_K$。

枚举$K$,对于每一个$Pre_K$,求出它所对应的最长的$Suf$即为$F_{Pre_K}$,这个用$Suf_{S-K}$更新即可,要考虑$F_i+1$可以更新$F_i$。

所以最后枚举每一个坐标$i$,找到它第一层所在的段的左右端点$L,R$,看$F_{L-1}$是否能覆盖到$R$即可。

由于状态数是$2^{\log_2 V}$,所以它是严格小于$V$的,所以最终复杂度为$O(n\log V+V)$。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define M 200020
#define INF 1000001000
using namespace std;
const int BS=1<<19;char BF[BS],OT[BS],*SZ=OT,*HD,*TL;
const char *ED=OT+BS-1; int Top;
char Getchar(){if(HD==TL)TL=(HD=BF)+fread(BF,1,BS,stdin);return *HD++;}
void flush(){fwrite(OT,1,SZ-OT,stdout);}
void Putc(char c){*SZ++ =c;if(SZ==ED) flush(),SZ=OT;}
int read(){
int nm=0,fh=1; char cw=Getchar();
for(;!isdigit(cw);cw=Getchar()) if(cw=='-') fh=-fh;
for(;isdigit(cw);cw=Getchar()) nm=nm*10+(cw-'0');
return nm*fh;
}
void TK(bool x){
if(x) Putc('P'); else Putc('I'),Putc('m'),Putc('p'); Putc('o');
Putc('s'),Putc('s'),Putc('i'),Putc('b'),Putc('l'),Putc('e'),Putc('\n');
}
int tot,n,m,pos[M],L[M][21],R[M][21],V[40],rt;
int RF[M<<3],LF[M<<3],G[M],D[M],MAXN;
int main(){
n=read(),m=read();
for(int i=1;i<=n;i++) pos[i]=read(),D[i]=pos[i]-pos[i-1],G[i]=-(INF<<1);
while(m) V[tot++]=m,m>>=1; tot++;
for(int k=0;k<tot;k++){
for(int i=1;i<=n;i++){
R[i][k]=max(R[i-1][k]-1,1);
while(i+R[i][k]<=n&&D[i+R[i][k]]<=V[k]) R[i][k]++;
}
for(int i=n;i;i--){
L[i][k]=max(L[i+1][k]-1,1);
while(i-L[i][k]>0&&D[i-L[i][k]+1]<=V[k]) L[i][k]++;
}
} MAXN=(1<<tot);
for(int i=2;i<MAXN;i+=2){
for(int k=1;k<tot;k++){
int w=(1<<k); if(!(i&w)) continue;
LF[i]=max(LF[i],LF[i^w]+R[LF[i^w]+1][k]);
RF[i]=max(RF[i],RF[i^w]+L[n-RF[i^w]][k]);
} LF[i]=min(LF[i],n),RF[i]=min(RF[i],n);
}
for(int k=0;k<MAXN;k+=2) G[LF[k]]=max(G[LF[k]],RF[(MAXN-2)^k]);
for(int i=n-1;i>=0;i--) G[i]=max(G[i],G[i+1]);
for(int i=1;i<=n;i++) TK(G[i-L[i][0]]+R[i][0]+i-1>=n); flush();return 0;
}

Agc012_E Camel and Oases的更多相关文章

  1. AGC012 - E: Camel and Oases

    原题链接 题意简述 沙漠中有个排成一条直线的绿洲,一头储水量为的骆驼. 骆驼有两个操作: 走到距离在V以内的一个绿洲. 飞到任意一个绿洲,但V减少一半.V=0时不能飞. 问骆驼依次从每个绿洲出发,能否 ...

  2. 【AtCoder】【模拟】【模型转化】Camel and Oases(AGC012)

    题意: 有一个骆驼,n个绿洲遍布在数轴上,第i个绿洲的坐标为x[i],保证x[i]单增.骆驼的驼峰有体积初始值V.当驼峰的体积变为v的时候,驼峰中至多只能够存储v L的水.骆驼希望走完所有的绿洲,并且 ...

  3. 【AGC012E】 Camel and Oases ST表+状压dp

    题目大意:一排点,两点间有距离. 初始你有一个行走值$v$,如果相邻两点距离不超过$v$你可以自由在这两点行走. 当$v$大于$0$时,你可以选择某一时刻突然飞到任意点,这样做后$v$会减半(下取整) ...

  4. 【agc012E】Camel and Oases

    Portal --> agc012 Description 有一排点,两点间有一定距离,初始的时候有一个行走值\(v\),如果说两点间距离不超过\(v\),那么可以在这两点间自由行走,如果当前\ ...

  5. [AGC012E]Camel and Oases

    题意:有$n$个数轴上的绿洲,给定它们的坐标,有一只骆驼想要访问所有绿洲,当它的驼峰容量为$V$时,它可以走到和当前绿洲距离$\leq V$的绿洲,并可以继续走,它也可以用一次跳跃到达任意一个绿洲,只 ...

  6. AtCoder Grand Contest 012

    AtCoder Grand Contest 012 A - AtCoder Group Contest 翻译 有\(3n\)个人,每一个人有一个强大值(看我的假翻译),每三个人可以分成一组,一组的强大 ...

  7. 【AtCoder】AGC012

    AGC012 A - AtCoder Group Contest 从最后开始间隔着取就行 #include <bits/stdc++.h> #define fi first #define ...

  8. A♂G&C012

    A♂G&C012 A AtCoder Group Contest 从大到小sort后输出\(a_2+a_4+a_6+\ldots a_{2n}\) 好♂啊,只会背结论/kk B Splatte ...

  9. Camel运行原理分析

    Camel运行原理分析 以一个简单的例子说明一下camel的运行原理,例子本身很简单,目的就是将一个目录下的文件搬运到另一个文件夹,处理器只是将文件(限于文本文件)的内容打印到控制台,首先代码如下: ...

随机推荐

  1. c_str()方法使用

    语法: const char *c_str(); c_str()函数返回一个指向正规C字符串的指针常量, 内容与本string串相同. 这是为了与c语言兼容,在c语言中没有string类型,故必须通过 ...

  2. Idea 远程调试jenkins 项目

    1.Jenkins配置 jenkins 服务启动时 需要在jvm启动项里加入如下代码: -Xdebug -Xrunjdwp:transport=dt_socket,suspend=n,server=y ...

  3. 【BZOJ5037】[Jsoi2014]电信网络 最大权闭合图

    [BZOJ5037][Jsoi2014]电信网络 Description JYY创建的电信公司,垄断着整个JSOI王国的电信网络.JYY在JSOI王国里建造了很多的通信基站.目前所有的基站都是使用2G ...

  4. 【bzoj2226】[Spoj 5971] LCMSum 欧拉函数

    题目描述 Given n, calculate the sum LCM(1,n) + LCM(2,n) + .. + LCM(n,n), where LCM(i,n) denotes the Leas ...

  5. 九度OJ 1250:矩阵变换 (矩阵运算)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:95 解决:47 题目描述: 对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)某一个元素也加一, 现给出一正数矩 ...

  6. rm_invalid_file

    import xlrd import time import sys import os import requests import sqlite3 import threading curPath ...

  7. 如何使用Django实现用户登录验证

    最初开始搞用户登录验证的时候感觉没什么难的,不就是增删改查中的查询数据库么,但是还是遇到许多小问题,而且感觉在查询数据库的时候,要把前端的数据一条一条的进行比对,会导致我的代码很丑,而且方式很不智,所 ...

  8. sublime运行Python

    1.首先安装Python 我这里安装的是Python的3.7版本. 这里有两种安装方式 第一种: 默认路径安装,勾选添加到path复选框(这种情况,sublime可以直接运行Python了) 第二种: ...

  9. 牛客小白月赛1 E 圆与三角形 【数学】

    题目链接 https://www.nowcoder.com/acm/contest/85/E 思路 在三角形中,这一串东西的值恒为1 又 SIN A 的最大值 为1 所以 这串式子的最大值 就是 r ...

  10. Mysql——JDBC编程 简单的例子

    第一类连接Mysql方法见下图: 第二类连接Mysql方法:(跟第一类差不多,并提供查询操作) 首先在Mysql中建立testjdbc数据库,在该数据库下面建立Student表: 参考代码: CREA ...