原题链接

题意简述

沙漠中有n(n≤2×105)个排成一条直线的绿洲,一头储水量为V(V≤2×105)的骆驼。
骆驼有两个操作:

  • 走到距离在V以内的一个绿洲。
  • 飞到任意一个绿洲,但V减少一半。V=0时不能飞。

问骆驼依次从每个绿洲出发,能否一次性遍历所有绿洲。

分析

首先预处理出 V=V0 时哪些绿洲之间是可以随便走的,对于每个V0扫一遍即可。时间复杂度为O(nlog2V)。

每飞一次相当于下一层。题目转化成钦定第一条线段,然后从每一层选一条线段,问能否覆盖整个区间。
万万没想到,这道题居然是状压DP!!!

s中的后起第i位为1表示从第i层选出了一条线段。
f1[s]表示状态s时从1起向右最远能延伸到哪,f2[s]表示状态s时从n起向左最远能延伸到哪。
f1[s]=max(f1[s],upFind(f1[s0]))
f2[s]=min(f2[s],lowFind(f2[s0]−1))
意义是从s0加上一条线段能延伸到哪。这个转移方程和我的写法有关,具体看代码。
时间复杂度O(log2V⋅log2n⋅2log2V+1)=O(Vlog2nlog2V)

检查答案时,对于第一层的每一条线段,寻找是否存在s,使得f1[s],f2[U−s−1]和该线段覆盖整个区间。表示用状态s这些线段尽可能扩展左半部分,用剩下的线段(不包括第一层)尽可能扩展右半部分,再加上第一层的这条线段。
最大时间复杂度O(n⋅2log2V)=O(nV),GG ╮(╯﹏╰)╭
但实际上,第一层的线段条数是不能超过log2V+1的。因为飞log2V+1次后V0=0,并且下一层的条数比上一层只多不少,要是第一层就超过log2V+1那么不可能遍历所有绿洲。
所以最大时间复杂度为O(Vlog2V)。

总时间复杂度最大为O(nlog2V+Vlog2nlog2V)。

实现

a[i][j]记录第i层的第j条线段的右端点。特别地,a[i][0]记录第i层线段的条数。
upFind(x)找出第一个严格大于x的右端点。这个右端点所在的区间一定能延伸当前的f1。
lowFind(x−1)找出第一个严格小于x-1的右端点。这个右端点的下一个区间一定能延伸当前的f2。如果写lowFind(x),要是找到x-1的话,说明有一段以x-1为右端点的区间以及一段以x为左端点的区间。这时候明明可以加入前者,实际上却加入了后者,导致问题。

代码

//Camel and Oases
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long lint;
int const N=2e5+10;
int const S=1<<19;
int n,V;
lint d[N];
int logV,a[25][N];
int U,f1[S],f2[S];
int upFind(int a[],int x)
{int L=1,R=a[0];while(L<R-1){int mid=(L+R)>>1;if(a[mid]<=x) L=mid+1;if(a[mid]>x) R=mid;}if(a[L]>x) return a[L];else return a[R];
}
int lowFind(int a[],int x)
{int L=1,R=a[0];while(L<R-1){int mid=(L+R)>>1;if(a[mid]<x) L=mid;if(a[mid]>=x) R=mid-1;}if(a[R]<x) return a[R]+1;else return a[L]+1;
}
int main()
{scanf("%d%d",&n,&V);logV=0;while((1<<logV)<=V) logV++;logV++;for(int i=1;i<=n;i++) scanf("%lld",&d[i]),d[i-1]=d[i]-d[i-1];d[n]=0;for(int i=1;i<=logV;i++){a[i][0]=1;for(int j=1;j<=n;j++){a[i][a[i][0]]=j;if(d[j]>(V>>(i-1))) a[i][0]++;}}if(a[1][0]>logV){for(int i=1;i<=n;i++) printf("Impossible\n");return 0;}U=(1<<logV)-1;for(int s=0;s<=U;s++) f1[s]=0,f2[s]=n+1;for(int s=0;s<=U;s+=2)for(int i=2;i<=logV;i++){int s0=1<<(i-1);if(s&s0) continue;f1[s|s0]=max(f1[s|s0],upFind(a[i],f1[s]));f2[s|s0]=min(f2[s|s0],lowFind(a[i],f2[s]-1));}for(int i=1;i<=a[1][0];i++){bool f=false;int fr=a[1][i-1]+1,to=a[1][i];if(i==1) fr=1;for(int s=0;s<=U&&!f;s+=2)if(fr<=f1[s]+1 && f2[U-s-1]-1<=to) f=true;if(f) for(int j=fr;j<=to;j++) printf("Possible\n");else for(int j=fr;j<=to;j++) printf("Impossible\n");}return 0;
}

注意

  • 因为最多飞log2V+1次,所以全集状态U=2log2V+1−1,体现在题目中为219,而不是218。
  • a[i][0]做他用,有些地方写的可能会麻烦一些。

转载于:https://www.cnblogs.com/VisJiao/p/8485770.html

AGC012 - E: Camel and Oases相关推荐

  1. 【DP】AGC012 E Camel and Oases

    分析: 有点套路的状压题 很显然,最多logV层,所以可以记录每一层的选取状态(第一层保证不能选). 定义f1(mask)f1(mask)f1(mask)表示选取状态为mask时,从最左端开始连续覆盖 ...

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

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

  3. 【agc012E】Camel and Oases

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

  4. agc012E Camel and Oases(状压dp+思路题)

    这题神啊.状压dp你敢信?思维难度爆表还有一堆细节要注意???orz Visjiao 原题链接:http://agc012.contest.atcoder.jp/tasks/agc012_e 大神题解 ...

  5. AT2365-[AGC012E]Camel and Oases【状压dp】

    正题 题目链接:https://www.luogu.com.cn/problem/AT2365 题目大意 一个数轴上有nnn个点,开始你有个水壶容量为VVV,你每次有两个操作 走到一个距离与你不超过V ...

  6. [agc012e]Camel and Oases

    前言 很容易的就发现了只有log次跳跃. 然后状压DP. 似乎就是个简单题吧(怎么比12c还简单) 题意 一排点,两点间有距离. 初始你有一个行走值v,如果相邻两点距离不超过v你可以自由在这两点行走. ...

  7. AtCoder Grand Contest 012 E Camel and Oases 状压dp

    Description 有一个容量为V的包,n个接水点,坐标分别为x[] 有两种移动方式: 若两个接水点之间的距离不超过此时包的容量v,那么就可以移动 若此时v不等于0,那么可以使v=v/2(下取整) ...

  8. AtCoder Grand Contest 012 E - Camel and Oases 状压dp

    题意 平面上有n个点.初始有V的权值,每次可以从一个点走到与他距离不超过V的点,当V>0时也可以让V/2且到达任意一个点.问从每个点出发能否遍历所有点. n,V<=200000 分析 显然 ...

  9. AtCoder - 2365 Camel and Oases

    标签:状压DP 题目 题目传送门 数轴上有n个点,问从哪些点出发可以按以下方式经过所有点至少一次: 移动到一个距离不超过m的点: 移动到任意一个点,然后m/=2. n,m<=200000 分析 ...

最新文章

  1. LINUX samba的安装使用
  2. 解决页面换行因标点符号不能出现在每一行的开头,导致提前换行,中间出现空隙的问题
  3. .net core独立发布文件过多的问题
  4. Eclipse Validating减少不必要的验证
  5. java项目经验行业_行业研究以及如何炫耀您的项目
  6. 浙江大学计算机学院研究生论文盲审,浙江理工大学研究生学位论文盲审实施办法...
  7. fastjson生成json时Null属性不显示
  8. 快速了解Linux ps命令
  9. 使用TypoDetect检测相似域名
  10. 11-24 EDEM-FLUENT 耦合步骤
  11. 影音先锋 android下载地址,影音先锋手机版-影音先锋下载v5.8.2 安卓手机版-西西软件下载...
  12. javascript语法
  13. PDF文件转换成图片的格式
  14. 2.4g低功耗SI24R1校园答题器
  15. Raspberry Pi 4B SSH、VNC及串口连接配置
  16. 大数据在智慧消防领域的应用
  17. 关于反向传播算法中几个公式的推导
  18. 我是如何投资数字货币的(1.2版)
  19. iOS 内存泄漏检测 Instruments Leaks
  20. 使用python执行uds诊断

热门文章

  1. java mysql 生僻字 乱码_mysql 生僻字乱码
  2. SAP WM上架策略为Fixed Bin的Storage Type如何以FIFO出库?
  3. poi设置excel行高
  4. 格灵深瞳——人脸识别算法测试FRVT
  5. 安装黑苹果提示未能安装_黑苹果安装过程中经常出现的问题及解决方法
  6. Coursera 学习记录:Tomorrow never knows?(实现日期加一的操作)
  7. 全球第二!食在爱尔兰,安全感满满!
  8. 套路(Jony J)
  9. vue项目 如何解决浏览器缓存问题
  10. imvu为什么显示无法连接服务器,IMVU服务器错误怎么办 服务器无法连接解决办法...