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++测试程 ...
随机推荐
- mybatis一对多
mapper.xml <mapper namespace="com.oracle.dao.one2manyDao"> <resultMap type=" ...
- 获取Bootstrap-Table的所有内容,修改行内容
var allTableData = $tableLeft.bootstrapTable('getData');//获取表格的所有内容行 var flag = false; for( i=0;i< ...
- python使用cx_oracle连接oracle数据库
http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html---下载instantclient-basic-linux.x ...
- 命令行添加PATH
如何设置PATH 命令:echo "export PATH=xxxxxx:$PATH" >> ~/.bash_profile 解释:把"export PATH ...
- fatal error C1083: 无法打开预编译头文件:“Debug\opencv.pch”: No such file or directory
stdafx.cpp右键——属性,预编译头选“创建”,其它cpp选“使用”. 调试不能优化.
- vue 单页面(SPA) history模式调用微信jssdk 跳转后偶尔 "invalid signature"错误解决方案
项目背景 vue-cli生成的单页面项目,router使用history模式.产品会在公众号内使用,需要添加微信JSSDK,做分享相关配置. 遇到的问题 相关配置与JS接口安全域名都已经ok,发布后, ...
- NullpointerException真的一定要被预防?
毫无疑问,空指针NullpointerException是我们最常遇到异常,没有之一! 在刚进入编程职业时,我想,大部分进入的同学肯定会受到前辈们的叮咛:一定要防止空指针,这是个低级错误.你们不是?好 ...
- java序员必备的十大技能
想成为一名出色的Java程序员么?本文将为大家重点介绍程序员必备的十大技能,成就您的梦想. 1.语法:必须比较熟悉,在写代码的时候IDE的编辑器对某一行报错应该能够根据报错信息知道是什么样 ...
- Cocos Console命令总结
1. 工程创建 使用Cocos Console创建工程非常简单,安装完cocos命令之后,只需要在需要创建工程的目标目录下打开终端或命令行工具,输入下面的命令即可: cocos new -l js P ...
- mysql 免安装配置问题
摘要: MySQL是一个小型关系型数据库管理系统,MySQL被广泛地应用在Internet上的中小型网站中.由于其体积小.速度快.总体拥有成本低,尤其是开放源码这一特点,许多中小型网站为了降低网站总体 ...