NOIp2016 蚯蚓 【二叉堆/答案单调性】By cellur925
$Sol$
$50pts$:我们考虑$q==0$的情况,每次在所有的蚯蚓中找到一只长度最大的,这非常二叉堆。所以我们可以用一个优先队列,随便水一下就有50分。($NOIp$的分真这么好拿?)
(理论得分60分,由于种种常数等的原因,实际会达到50分)
#include<cstdio>
#include<algorithm>
#include<queue> using namespace std; int n,m,can,u,v,t;
int tim[];
priority_queue<int>q; int main()
{
scanf("%d%d%d%d%d%d",&n,&m,&can,&u,&v,&t);
if(can==)
{
for(int i=;i<=n;i++)
{
int x=;
scanf("%d",&x);q.push(x);
}
for(int i=;i<=m;i++)
{
int tmp=q.top();q.pop();tim[i]=tmp;
int a=u*tmp/v;int b=tmp-a;
q.push(a);q.push(b);
}
for(int i=t;i<=m;i+=t)
printf("%d ",tim[i]);
printf("\n");
for(int i=;i<=n+m;i++)
{
if(q.empty()) break;
if(i%t==) printf("%d ",q.top());
q.pop();
}
}
return ;
}
50pts
$85pts$:我们不得不考虑每次切蚯蚓后其他的蚯蚓长度情况(为了拿到更多的部分分),我们不妨考虑下线段树和分块中的思想。
Chemist:线段树中最精妙的设计是什么?
我:懒标记!
Chemist:对!你就往这想。
我们并不需要每次都把其他蚯蚓的长度增加,而是等需要他们的时候再增加。于是,我们同样在维护一个二叉堆(优先队列),但是这里面存的是还是最初的蚯蚓们长度。我们再维护一个增量即可。
另外这道题是著名的卡常数代表,开始我80分是因为开了$longlong$,有位老哥和我打暴力的方法一样,然后它用$int+double$转化卡到了85分。
#include<cstdio>
#include<algorithm>
#include<queue> using namespace std;
typedef long long ll; ll n,m,can,u,v,t;
ll sigma;
priority_queue<ll>q; void re(ll &x)
{
x=;
char ch=getchar();
bool flag=false;
while(ch<''||ch>'') flag|=(ch=='-'),ch=getchar();
while(ch>=''&&ch<='') x=(x<<)+(x<<)+(ch^),ch=getchar();
x=flag ? -x : x;
} int main()
{
re(n),re(m),re(can),re(u),re(v),re(t);
for(register int i=;i<=n;i++)
{
ll x=;
re(x);q.push(x);
}
for(register int i=;i<=m;i++)
{
ll tmp=q.top()+sigma;q.pop();//输出要把增量带上
if(i%t==) printf("%lld ",tmp);
ll a=1ll*u*tmp/v;ll b=tmp-a;
a-=sigma;b-=sigma;//进优先队列的都是不带增量的
a-=can;b-=can;//为了防止以后被认为在这时刻增加了 现在先减去
q.push(a);q.push(b);
sigma+=can;//继续维护增量
}
printf("\n");
for(register int i=;i<=n+m;i++)
{
if(q.empty()) break;
if(i%t==) printf("%lld ",q.top()+sigma);
q.pop();
}
return ;
}
85pts
$100pts$:正解的思维难度还是有的,先被切掉的蚯蚓长度一定比后被切掉的蚯蚓长度大。

(引用自@aiyougege,侵删)
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath> using namespace std;
typedef long long ll; ll n,m,q,t,sigma;
double u,v,p;
ll qiuyin[];
queue<ll>q1,q2,qq; bool cmp(ll a,ll b)
{
return a>b;
} int main()
{
scanf("%lld%lld%lld%lf%lf%lld",&n,&m,&q,&u,&v,&t);
p=u/v;
for(int i=;i<=n;i++) scanf("%lld",&qiuyin[i]);
sort(qiuyin+,qiuyin++n,cmp);
for(int i=;i<=n;i++) qq.push(qiuyin[i]);
for(int i=;i<=m;i++)
{
ll len=,len1=,len2=;
ll qwq=-1e16-,qaq=-1e16-,orz=-1e16-;
if(!q1.empty()) qwq=q1.front();
if(!q2.empty()) qaq=q2.front();
if(!qq.empty()) orz=qq.front();
if(!q1.empty()&&qwq>=qaq&&qwq>=orz) q1.pop();
else if(!q2.empty()&&qaq>=qwq&&qaq>=orz) q2.pop();
else if(!qq.empty()&&orz>=qaq&&orz>=qwq) qq.pop(); len=max(max(qwq,qaq),orz);len+=sigma;
if(i%t==) printf("%lld ",len);
len1=floor(p*len)-q-sigma;
len2=len-floor(p*len)-q-sigma;
q1.push(len1),q2.push(len2);
sigma+=q;
}
printf("\n");
for(int i=;i<=n+m;i++)
{
ll len=,qwq=-1e16-,qaq=-1e16-,orz=-1e16-;
if(!q1.empty()) qwq=q1.front();
if(!q2.empty()) qaq=q2.front();
if(!qq.empty()) orz=qq.front();
if(!q1.empty()&&qwq>=qaq&&qwq>=orz) q1.pop();
else if(!q2.empty()&&qaq>=qwq&&qaq>=orz) q2.pop();
else if(!qq.empty()&&orz>=qaq&&orz>=qwq) qq.pop();
len=max(max(qwq,qaq),orz)+sigma;
if(i%t==) printf("%lld ",len);
}
return ;
}
但是期间奥妙重重WA了无数次,也不知怎么肥事。重敲就活过来了,可能是精度问题的锅,还需要注意下。
小结:NOIp的部分分还是给的很足的,有时还可能不小心敲成正解?第二题还是要重视,尽量多拿分。
NOIp2016 蚯蚓 【二叉堆/答案单调性】By cellur925的更多相关文章
- 洛谷P2827 [NOIP2016 提高组] 蚯蚓 (二叉堆/队列)
容易想到的是用二叉堆来解决,切断一条蚯蚓,其他的都要加上一个值,不妨用一个表示偏移量的delta. 1.取出最大的x,x+=delta: 2.算出切断后的两个新长度,都减去delta和q: 3.del ...
- poj 3253 初涉二叉堆 模板题
这道题很久以前就做过了 当时是百度学习了优先队列 后来发现其实还有个用sort的办法 就是默认sort排序后 a[i]+=a[i-1] 然后sort(a+i,a+i+n) (大概可以这样...答案忘了 ...
- 【BZOJ 1129】[POI2008]Per 二叉堆
这个东西读完题之后,就能知道我们要逐位计算贡献.推一下式子,会发现,这一位的贡献,是当前剩余的数字形成的序列的总数,乘上所剩数字中小于s上这一位的数的个数与所剩数字的总数的比.所以我们维护“当前剩余的 ...
- AC日记——二叉堆练习3 codevs 3110
3110 二叉堆练习3 时间限制: 3 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 给定N(N≤500,000)和N个整 ...
- codevs 3110 二叉堆练习3
3110 二叉堆练习3 http://codevs.cn/problem/3110/ 题目描述 Description 给定N(N≤500,000)和N个整数(较有序),将其排序后输出. 输入描述 I ...
- 数据结构图文解析之:二叉堆详解及C++模板实现
0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...
- POJ 2010 - Moo University - Financial Aid 初探数据结构 二叉堆
考虑到数据结构短板严重,从计算几何换换口味= = 二叉堆 简介 堆总保持每个节点小于(大于)父亲节点.这样的堆被称作大根堆(小根堆). 顾名思义,大根堆的数根是堆内的最大元素. 堆的意义在于能快速O( ...
- 二叉堆(一)之 图文解析 和 C语言的实现
概要 本章介绍二叉堆,二叉堆就是通常我们所说的数据结构中"堆"中的一种.和以往一样,本文会先对二叉堆的理论知识进行简单介绍,然后给出C语言的实现.后续再分别给出C++和Java版本 ...
- 二叉堆(二)之 C++的实现
概要 上一章介绍了堆和二叉堆的基本概念,并通过C语言实现了二叉堆.本章是二叉堆的C++实现. 目录1. 二叉堆的介绍2. 二叉堆的图文解析3. 二叉堆的C++实现(完整源码)4. 二叉堆的C++测试程 ...
随机推荐
- 最小公倍数(Least Common Multiple)
最小公倍数=两个数的乘积/两个数的最大公约数. 接上篇求最大公约数方法,最小公倍数的代码例如以下: public class LCM { //最小公倍数=两数乘积/最大公约数 public stati ...
- SQL 通配符及其使用
Sql Server中通配符的使用 通配符_ "_"号表示任意单个字符,该符号只能匹配一个字符."_"可以放在查询条件的任意位置,且只能代表一个字符.一个汉字只 ...
- 《STL源代码剖析》---stl_deque.h阅读笔记(2)
看完,<STL源代码剖析>---stl_deque.h阅读笔记(1)后.再看代码: G++ 2.91.57,cygnus\cygwin-b20\include\g++\stl_deque. ...
- intellij IDEA 更新java后不用重启tomcat
最近项目大了,每次修改后重启都要等和很久,那个煎熬…… 为了解决这个问题,万能的Google 装了这个 JREBEL 5.63最新的 安装步骤: 一.IDEA在线搜索 jrebel 安装 二.破 ...
- Designing a RESTful API with Python and Flask 201
rest服务器的搭建 - CSDN博客 http://blog.csdn.net/zhanghaotian2011/article/details/8760794 REST的架构设计 REST(Rep ...
- DeepLearningFlappyBird-深度学习玩游戏-1-环境搭建
-------------------------------------------------------------------------------------- https://githu ...
- shell mv
mv $a"/"$b"/"* $a"/"$b"/preview" 移动某个文件夹下的所有文件 使用* 但*不用双引号
- redis13-----配置文件
==配置文件全解=== ==基本配置 daemonize no 是否以后台进程启动 databases 创建database的数量(默认选中的是database ) #刷新快照到硬盘中,必须满足两者要 ...
- JavaScript数组遍历:for、foreach、for in、for of、$.each、$().each的区别
一.for Javascript中的for循环,它用来遍历数组 var arr = [1,2,3,4] for(var i = 0 ; i< arr.length ; i++){ console ...
- HDU2295 Radar —— Dancing Links 可重复覆盖
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2295 Radar Time Limit: 2000/1000 MS (Java/Others) ...