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++测试程 ...
随机推荐
- poj1703 Find them,Catch them 【并查集】
做过一些的带权并查集,再来做所谓的"种类并查集",发现好像就顿悟了. 种类并查集与带权并查集实质上的区别并不大. 关键的区别就是种类并查集仅仅是带权并查集再弄个%取余操作而已.然后 ...
- 翻译:A Tutorial on the Device Tree (Zynq) -- Part V
A Tutorial on the Device Tree (Zynq) -- Part V Application-specific data 之前提过,设备树中是一些特殊信息,这样一个驱动可以管理 ...
- 使用$.when()解决AJAX异步难题之:多个ajax操作进行逻辑与(and)
上一篇文章"JQuery.deferred提供的promise解决方式",提到了javascript异步操作的3个问题,以及javascript Promise入门.如今我们看下怎 ...
- thinkphp Class 'PDO' not found 错误
thinkphp Class 'PDO' not found 错误,原因mysql5.7.26缺少pdo驱动,需要安装php的pdo和pdo_mysql扩展 本文以centOS为例 1.进入PHP源码 ...
- SSM整理笔记2——jar包整理
github:https://github.com/lakeslove/SSM 需要的jar包 springMVC和spring: spring.RELEASE.jar spring.RELEASE. ...
- 启用了不安全的HTTP方法解决办法 IBM APPSCAN
启用了不安全的HTTP方法解决办法 IBM APPSCAN 安全风险: 可能会在Web 服务器上上载.修改或删除Web 页面.脚本和文件. 可能原因: Web 服务器 ...
- python dictionary的遍历
d = {'x':1, 'y':3, 'z':2} for k in d: print d[k] 直接遍历k in d的话,遍历的是dictionary的keys. 2 字典的键可以是任何不可变 ...
- IDEA中Git的应用场景
工作中多人使用版本控制软件协作开发,常见的应用场景归纳如下: 假设小组中有两个人,组长小张,组员小袁 场景一:小张创建项目并提交到远程Git仓库 场景二:小袁从远程git仓库上获取项目源码 场景三:小 ...
- Mac OS X 开发环境搭建之利用 Parallel Desktop 安装 CentOS 7 [转载]
背景 在企业级软件系统中,数据库的地位是比较高的,而且一般都要求支持多种数据库,如 Oracle. DB2.MySQL 等,它们的最新版本大多都不再支持 Mac OS X 系统,所以装一个 Linux ...
- p1697食物链
动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A.现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种.有人用两种说法 ...