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++测试程 ...
随机推荐
- cin,和几个get函数的用法
1.cin.get(字符变量名):用来接收字符 ch = cin.get(); cin.get(ch); 以上两者均可以 2.cin.get(字符数组名,接收字符数目)用来接收一行字符串,可以接收空格 ...
- 写2个线程,其中一个线程打印1~52,另一个线程打印A~z,打印顺序应该是12A34B45C……5152Z
我写的 class LN { private int flag = 0; public static char ch = 'A'; public static int n = 1; public sy ...
- 第04章-VTK基础(2)
[译者:这个系列教程是以Kitware公司出版的<VTK User's Guide -11th edition>一书作的中文翻译(出版时间2010年,ISBN: 978-1-930934- ...
- Metasploit学习笔记之——情报搜集
1.情报搜集 1.1外围信息搜索 1.1.1通过DNS和IP地址挖掘目标网络信息 (1)whois域名注冊信息查询(BT5.kali专有):root@kali:~# whois testfire.ne ...
- openwrt gstreamer实例学习笔记(三.深入了解gstreamer 的 Element)
在前面的部分,我们简要介绍过 GstElementFactory 可以用来创建一个element的实例,但是GstElementFactory不仅仅只能做这件事,GstElementFactory作为 ...
- pyspark 连 MongoDB复制集
解决问题思路: 核心:0-理解pyspark的执行与java jar的关系: 1-看控制台,看日志: 2-jar缺不缺,版本号,放哪里. [root@hadoop1 mylocalRepository ...
- https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
- ap和路由器有什么区别 ap和路由器的区别介绍【图文】
现在能够摆脱网线限制能够自由方便上网的WiFi和无线网络也来越流行,很多酒店.饭店.宾馆.办公楼等地方都会提供无线网络.而能够提供无线网络的设备有很多,现在我们介绍的是无线ap和无线路由器.那么,ap ...
- exception.py
try: raise Exception except Exception as e: print(e) try: raise Exception('comment') except Exceptio ...
- 【USACO 2006 November Gold】Corn Fields
[题目链接] 点击打开链接 [算法] 状压DP [代码] #include<bits/stdc++.h> using namespace std; #define MAXN 12 #def ...