3441: 乌鸦喝水

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 311  Solved: 117
[Submit][Status][Discuss]

Description

【题目背景】
    一只乌鸦在自娱自乐,它在面前放了n个有魔力的水缸,水缸里装有无限的水。
【题目描述】
    他准备从第1个水缸飞到第n个水缸,共m次。在飞过一个水缸的过程中,如果他能够得着水缸里的水,即水缸口到水面距离小于等于乌鸦能够得着的深度,那它就会喝水缸里的水。每喝一次水,所有水缸里的水位都会下降,第i个水缸里的水位会下降Ai,注意喝水是瞬间的,如果乌鸦刚好够得着,但喝完之后够不着,也视为喝到一次,水位也会相应的下降。

Input

共有3行。第一行有三个正整数n、m和x,用空格隔开。n表示水缸的数量,m表示乌鸦飞的次数,x表示乌鸦能够得着的深度。第二行,有n个用空格隔开的正整数,第i个数为第i个水缸中水缸口到水面的距离Wi。第三行,有n个用空格隔开的正整数,第i个为Ai。

Output

只有一行,这一行只有一个正整数,为这只乌鸦能喝到水的次数。

Sample Input

5 2 20
15 14 13 12 12
1 1 1 1 1

Sample Output

9

对的没错这是道模拟题,一看题目就很容易看出来

题目很好理解,先计算出每个水缸口下降多少次后就再也喝不到了

s[x].val表示第x个水缸口下降s[x].val后就再也喝不到

因为每喝一次所有水缸口都会下降,所以s[].val的大小关系永远不变,并且每次都是当前s[x].val最小的最先喝不了

假设可以喝无数趟,这题就是水题,答案就是max(a[x].val)(1<=x<=n),很好理解因为你每次无论喝哪杯结果都一样,所以你喝的顺序无所谓,最后一定喝了max(a[x].val)(1<=x<=n)次

但是这题你最多跑m趟,这样就有关系了,因为你一趟喝多少水取决于你之前的情况

比如(s[x].val的)数据 1 2 3 4 5,你喝一趟显然能喝5次,但数据5 1 2 3 4你第一趟就只能喝1次了

所以这题每次喝都的前后状态有关,那么怎么写呢,看上面红字

这样就有个大概的思路:每次都看当前s[x].val最小的在第几趟时喝到第几个水缸口时喝完

直到喝完m趟或者所有的水缸口都喝不到结束

思路还算简单处理起来可麻烦

①先算出是在第几趟的时候喝完当前s[x].val最小的水缸口:

这个整除下就好了,假设当前已经有p-1个水缸口喝不到水了,那么趟数就是(s[rak[p]].val-lost)/(n-(p-1)),其中rak[p]表示第p小的水缸口编号,lost表示已经整体下降了lost次(也就是乌鸦已经喝了lost次水)

②之后看喝到第几个编号的水缸时刚好喝完当前s[x].val最小的水缸

这里得用二分+线段树or树状数组判断,找到一个位置r满足r前面刚好有s[x].val个水缸口没有被喝完

这样喝到位置r时,当前s[x].val最小的水缸口刚好被喝完

②到这里可以判断下一个水缸口了

不过因为你这一趟还没有喝完,所以要先把这一趟喝完,注意r = min(r, x)!因为你不知道下一个水缸口在什么地方

有可能在x到r的范围内这样就有可能已经喝不到了,之后分情况讨论。。如果在min(r, x)前面那么肯定不影响,判断这一趟有没有喝完就好了,如果在后面需要继续二分,具体看代码吧

复杂度(nlognlogn)

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define LL long long
typedef struct
{LL id;LL val;
}Res;
Res s[100005];
LL n, rak[100005], tre[100005];
bool comp1(Res a, Res b)
{if(a.val<b.val || a.val==b.val && a.id<b.id)return 1;return 0;
}
bool comp2(Res a, Res b)
{if(a.id<b.id)return 1;return 0;
}
void Update(LL x)
{while(x<=n){tre[x]++;x += x&-x;}
}
LL Query(LL x)
{LL sum = 0;while(x){sum += tre[x];x -= x&-x;}return sum;
}
int main(void)
{LL lost;LL m, p, x, i, now, temp, l, r, mid;while(scanf("%lld%lld%lld", &n, &m, &p)!=EOF){for(i=1;i<=n;i++)scanf("%lld", &s[i].val);for(i=1;i<=n;i++){scanf("%lld", &x);s[i].val = max((p-s[i].val)/x+1, 0ll);s[i].id = i;}sort(s+1, s+n+1, comp1);for(i=1;i<=n;i++)rak[i] = s[i].id;sort(s+1, s+n+1, comp2);p = 1, lost = 0;memset(tre, 0, sizeof(tre));while(m){while(s[rak[p]].val-lost<=0 && p<=n)Update(rak[p++]);if(p>n)break;temp = min(m, (s[rak[p]].val-lost)/(n-p+1));lost += temp*(n-p+1);m -= temp;if(m==0)break;now = 1;while(now<=n){while(s[rak[p]].val-lost<=0 && p<=n)Update(rak[p++]);temp = n-(now-1)-(Query(n)-Query(now-1));while(rak[p]<now && s[rak[p]].val-lost-temp<=0 && p<=n)Update(rak[p++]);if(p>n)break;if(s[rak[p]].val-lost-temp>0){lost += temp;break;}temp = min(s[rak[p]].val-lost, rak[p]-(now-1)-(Query(rak[p])-Query(now-1)));lost += temp;l = 0, r = n-now+1;while(l<r){mid = (l+r+1)/2;if(now-1+mid-(now-1)-(Query(now-1+mid)-Query(now-1))<=temp)l = mid;elser = mid-1;}now = now+r;Update(rak[p++]);}m--;if(p>n || m==0)break;}printf("%lld\n", lost);}return 0;
}

bzoj 3441: 乌鸦喝水(说实话有生之年没有见过这么难的模拟)相关推荐

  1. BZOJ:3441 乌鸦喝水

    bzoj:3441 乌鸦喝水 题目传送门 Description 一只乌鸦在自娱自乐,它在面前放了n个有魔力的水缸,水缸里装有无限的水. 他准备从第1个水缸飞到第n个水缸,共m次.在飞过一个水缸的过程 ...

  2. NOIP模拟测试25「字符串·乌鸦喝水·所陀门王的宝藏(陀螺王)」

    字符串 题解 没看出catalan怎么办 dp打表啊! 考虑大力dp拿到30分好成绩!顺便收获一张表 打表发现$C_{n+m}^{m}-C_{n+m}^{m-1}$ 仔细观察然后发现其实就是之前的网格 ...

  3. Bzoj3441 乌鸦喝水

    Time Limit: 20 Sec  Memory Limit: 128 MB Submit: 258  Solved: 97 Description [题目背景] 一只乌鸦在自娱自乐,它在面前放了 ...

  4. 乌鸦喝水(异常处理版 _)

    由于都没有人发 索性便发出来吧..不过UT没写好 >_< [要求] 改写乌鸦喝水案例,扩展场景:乌鸦面对一堆大小不一的石头,且其中可能有伪装成石头的小炸药丸,面对的瓶子可能是普通的瓶子,也 ...

  5. 8.18 NOIP模拟测试25(B) 字符串+乌鸦喝水+所驼门王的宝藏

    T1 字符串 卡特兰数 设1为向(1,1)走,0为向(1,-1)走,限制就是不能超过$y=0$这条线,题意转化为从(0,0)出发,走到(n+m,n-m)且不越过$y=0$,然后就裸的卡特兰数,$ans ...

  6. 心田花开:一年级语文《乌鸦喝水》教案解析及练习题

    小学阶段是语文学习的起步阶段,掌握所学的基础知识是非常必要的.心田花开分享了<乌鸦喝水>知识点,希望能帮助大家更好的复习所学的知识. [原文]乌鸦喝水 一只乌鸦口渴了,到处找水喝.乌鸦看见 ...

  7. Java构造方法——乌鸦喝水场景描述

    Java构造方法--乌鸦喝水场景描述 1.场景简介: 2.对象分析 3. 对象创建 3.1 构造方法 3.2 类的创建 4.主方法调用以及结果 5. 总结 上次博客中学习了类与对象,这次便用其来描述一 ...

  8. “乌鸦喝水”是寓言吗?

    昨天看到一个报道:黑色的乌鸦真的会用工具把瓶子里的虫子吃到嘴,虽然不是去喝水,但是它能用小石子去升高瓶子里的水,最终吃到虫子.这简直是奇迹. 从<动物世界>里曾看到乌鸦用小树枝把洞里的虫子 ...

  9. 用matlab作乌鸦喝水,仿真程序动画作品--乌鸦喝水

    %作者:070408418 clear h1=figure(1); axis([0 30 0 35]);%建立坐标轴 axis off; xxx1=10; yyy1=36; aac='乌鸦要喝水'; ...

最新文章

  1. VB 6.0 计算鼠标的金额 字体
  2. eclipse中设置svn的commit快捷键
  3. 揭密|淘宝服务端千万级高并发架构的演进之路
  4. OpenShift 4 Hands-on Lab (0) - 教程说明和准备环境
  5. python 爬取上海体育彩票文章标题、时间、内容
  6. 机器学习模型融合方法综述
  7. PMP考试通关宝典一
  8. 三星s9更新android9.0,三星Galaxy S9/S9+ Android 9.0系统更新新进展
  9. java 报表模版 打印_Java报表工具技巧--Style Report报表套打模板设计
  10. 华硕笔记本计算机名称,华硕笔记本电脑有哪些型号 华硕笔记本电脑型号大全...
  11. weblogic安装以及异常解决方法【转】
  12. 查看hadoop版本
  13. zk的watcher机制
  14. Ubuntu:火狐浏览器加速下载(Flashgot+Aria2+Uget)
  15. mac上面的文件分割与合并
  16. AHRS(航姿参考系统)和IMU(惯性测量单元)的区别
  17. while (0) 是什么东东?
  18. 儿童学python第一课_初学Python(第一课)
  19. Objective-C 编程语言官网文档(一)-简介
  20. 推荐一首歌 - Just Another (Pete Yorn)

热门文章

  1. 怎样学好python编程-Python编程怎么学习好?老男孩Python入门
  2. python入门指南 许半仙txt-影帝的脑子坏了
  3. 基于DTW和HMM算法的语音识别系统对比研究-毕业小结
  4. 自动语音识别的原理是什么,它的作用是什么
  5. mysql c库 示例_选择MySQL数据库进行连接的简单示例
  6. tensorflow机器学习实战指南 源代码_小小白TensorFlow机器学习实战基础
  7. mysql主从错误1007_mysql主从错误:1032
  8. PowerDesigner生成的建表脚本中如何把对象的双引号去掉
  9. jmeter获得Response Headers,Response Body里的值
  10. Windows下给WSL子系统(Kali)换源,使用binwalk,outguess等工具