NOIP 2016 洛谷 P2827 蚯蚓 题解
题目描述
输入格式
输出格式
输入输出样例
样例输入一
样例输出一
样例输入二
样例输出二
样例输入三
//空行
样例输出三
说明/提示


【数据范围】

分析
m的最大值已经达到了7e6,这道题我们如果直接枚举的话肯定会超时
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn=+;
ll a[maxn];
bool cmp(ll aa,ll bb){ return aa>bb; }
priority_queue<ll> qq,xi,da;
int main(){
ll n,m,q,u,v,t;
scanf("%lld%lld%lld%lld%lld%lld",&n,&m,&q,&u,&v,&t);
for(ll i=;i<=n;i++){
scanf("%lld",&a[i]);
}
sort(a+,a++n,cmp);
ll head=,tail=n;
ll js=,ad=;
while(m--){
js++;
ll ans=-0x3f3f3f3f3f3f3f3f;
ll bb=ans,cc=ans,dd=ans;
if(!xi.empty()) bb=xi.top();
if(!da.empty()) cc=da.top();
if(head<=tail) dd=a[head];
ans=max(max(ans,bb),max(cc,dd));
if(ans==bb) xi.pop();
else if(ans==cc) da.pop();
else head++;
ans+=ad;
if(js%t==) printf("%lld ",ans);
ad=js*q;
ll left=u*ans/v;
ll right=ans-left;
left-=ad,right-=ad;
xi.push(min(left,right));
da.push(max(left,right));
}
printf("\n");
for(ll i=head;i<=tail;i++) {qq.push(a[i]);}
while(!xi.empty()) {qq.push(xi.top()),xi.pop();}
while(!da.empty()) {qq.push(da.top()),da.pop();}
ll cnt=;
while(!qq.empty()){
cnt++;
if(cnt%t==) printf("%lld ",qq.top()+ad);
qq.pop();
}
printf("\n");
return ;
}
这样写T掉是必然的,因为你用优先队列的话,每次插入时间复杂度都为O(logn)
这样的效率肯定会有数据T掉
那么我们再仔细想想,发现其实是没有必要用优先队列的
因为我们每一次都是先把最长的蚯蚓切割,所以先切的蚯蚓一定长于后切的蚯蚓
所以先切的蚯蚓的较长的部分一定长于后切的蚯蚓较长的部分,所以先切的蚯蚓的较短的部分一定长于后切的蚯蚓较短的部分
所以用来储存切割后两部分的两个堆都具有单调性,因此我们可以用数组模拟,这样会快很多
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
#define maxn 7000005
#define ll long long
ll a[maxn],xi[maxn],da[maxn];
bool cmp(ll aa,ll bb){ return aa>bb; }
int main(){
ll n,m,q,u,v,t;
scanf("%lld%lld%lld%lld%lld%lld",&n,&m,&q,&u,&v,&t);
for(register ll i=;i<=n;++i){
scanf("%lld",&a[i]);
}
sort(a+,a++n,cmp);
ll ha=,ta=n,hx=,hd=,tx=,td=;
ll js=,ad=;
ll mm=m;
while(mm--){
js++;
ll ans=-0x3f3f3f3f3f3f3f3f;
if(ha<=ta && a[ha]>=ans) ans=a[ha];
if(hx<=tx && xi[hx]>=ans) ans=xi[hx];
if(hd<=td && da[hd]>=ans) ans=da[hd];
if(a[ha]==ans && ha<=ta) ha++;
else if(xi[hx]==ans && hx<=tx) hx++;
else hd++;
ans+=ad;
if(js%t==) printf("%lld ",ans);
ll left=u*ans/v;
ll right=ans-left;
ad=js*q;
left-=ad,right-=ad;
xi[++tx]=min(left,right);
da[++td]=max(left,right);
}
printf("\n");
ll now=n+m;
for(ll i=;i<=now;++i){
ll ans=-0x3f3f3f3f3f3f3f3f;
if(ha<=ta && a[ha]>=ans) ans=a[ha];
if(hx<=tx && xi[hx]>=ans) ans=xi[hx];
if(hd<=td && da[hd]>=ans) ans=da[hd];
if(a[ha]==ans && ha<=ta) ha++;
else if(xi[hx]==ans && hx<=tx) hx++;
else hd++;
if(i%t==) printf("%lld ",ans+ad);
}
printf("\n");
return ;
}

这样的话,我们交到洛谷上可以过,但是在Vjudge上会T掉

于是,我又加上了读入优化、输出优化,以及register、inline等等,但发现还是会T

就像上面这样
后来我发现,其实没有必要写额外的读入优化、输出优化
一开始,我为了不炸int,把所有的变量都开成了long long
但实际上,有很多变量只用int就能解决,而且int比long long要快
只要把不必要的long long改成int就可以AC了

代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
#define maxn 7000005
#define ll long long
int a[maxn];
ll xi[maxn],da[maxn];
int cmp(int aa,int bb){ return aa>bb; }
int main(){
int n,m,q,u,v,t;
scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
for(int i=;i<=n;++i){
scanf("%d",&a[i]);
}
sort(a+,a++n,cmp);
int ha=,ta=n,hx=,hd=,tx=,td=;
ll js=,ad=;
int mm=m;
while(mm--){
js++;
ll ans=-0x3f3f3f3f3f3f3f3f;
if(ha<=ta && a[ha]>=ans) ans=a[ha];
if(hx<=tx && xi[hx]>=ans) ans=xi[hx];
if(hd<=td && da[hd]>=ans) ans=da[hd];
if(a[ha]==ans && ha<=ta) ha++;
else if(xi[hx]==ans && hx<=tx) hx++;
else hd++;
ans+=ad;
if(js%t==) printf("%lld ",ans);
ll left=u*ans/v;
ll right=ans-left;
ad=js*q;
left-=ad,right-=ad;
xi[++tx]=min(left,right);
da[++td]=max(left,right);
}
printf("\n");
int now=n+m;
for(int i=;i<=now;++i){
ll ans=-0x3f3f3f3f3f3f3f3f;
if(ha<=ta && a[ha]>=ans) ans=a[ha];
if(hx<=tx && xi[hx]>=ans) ans=xi[hx];
if(hd<=td && da[hd]>=ans) ans=da[hd];
if(a[ha]==ans && ha<=ta) ha++;
else if(xi[hx]==ans && hx<=tx) hx++;
else hd++;
if(i%t==) printf("%lld ",ans+ad);
}
printf("\n");
return ;
}
NOIP 2016 洛谷 P2827 蚯蚓 题解的更多相关文章
- 洛谷P2827 蚯蚓 题解
洛谷P2827 蚯蚓 题解 题目描述 本题中,我们将用符号 ⌊c⌋ 表示对 c 向下取整. 蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓. 蛐蛐国里现 ...
- 洛谷p2827蚯蚓题解
题目 算法标签里的算法什么的都不会啊 什么二叉堆?? qbxt出去学习的时候讲的,一段时间之前做的,现在才写到博客上的 维护3个队列,队列1表示最开始的蚯蚓,队列2表示每一次被切的蚯蚓被分开的较长的那 ...
- 洛谷 P2827 蚯蚓 题解
每日一题 day32 打卡 Analysis 我们可以想一下,对于每一秒除了被切的哪一个所有的蚯蚓都增长Q米,我们来维护3个队列,队列1表示最开始的蚯蚓,队列2表示每一次被切的蚯蚓被分开的较长的那一部 ...
- 洛谷 P2827 蚯蚓 解题报告
P2827 蚯蚓 题目描述 本题中,我们将用符号 \(\lfloor c \rfloor\) 表示对 \(c\) 向下取整,例如:\(\lfloor 3.0 \rfloor = \lfloor 3.1 ...
- 洛谷——P2827 蚯蚓
P2827 蚯蚓 题目描述 本题中,我们将用符号 \lfloor c \rfloor⌊c⌋ 表示对 cc 向下取整,例如:\lfloor 3.0 \rfloor = \lfloor 3.1 \rflo ...
- 洛谷P2827 蚯蚓——思路题
题目:https://www.luogu.org/problemnew/show/P2827 思路... 用优先队列模拟做的话,时间主要消耗在每次的排序上: 能不能不要每次排序呢? 关注先后被砍的两条 ...
- 洛谷 P2827 蚯蚓
题目描述 本题中,我们将用符号\lfloor c \rfloor⌊c⌋表示对c向下取整,例如:\lfloor 3.0 \rfloor= \lfloor 3.1 \rfloor=\lfloor 3.9 ...
- 洛谷P2827 蚯蚓(单调队列)
题意 初始时有$n$个蚯蚓,每个长度为$a[i]$ 有$m$个时间,每个时间点找出长度最大的蚯蚓,把它切成两段,分别为$a[i] * p$和$a[i] - a[i] * p$,除这两段外其他的长度都加 ...
- 洛谷P2827蚯蚓
题目 堆+模拟,还有一个小优化(优化后跟堆关系不大,而是类似于贪心). 如果不加优化的话,卡常可以卡到85. 思路是对于对每一秒进行模拟,用堆来维护动态的最大值,然后对于每个长度都加q的情况可以用一个 ...
随机推荐
- UVIYN MMDVM充电宝支持APRS与 YSF
需求就是要在APRS地图上显示对讲机位置 1.打开pi-star首页链接配置的专家(EXPERT)设置 下面链接快速打开 http://ip/admin/expert/edit_ysfgateway. ...
- 一篇关于Android M以后权限介绍的不错的文章
文章地址:http://www.jianshu.com/p/e1ab1a179fbb/
- (数据科学学习手札87)利用adjustText解决matplotlib文字标签遮挡问题
本文示例代码.数据已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 在进行数据可视化时我们常常需要在可视化作品 ...
- MSSQL(DAC环境一下一些特殊的访问方式)
MSSQL(在DAC环境下访问: 存储过程) Server name: admin:计算机名\实例名 or admin:IP地址\实例名 ...
- 用 Explain 命令分析 MySQL 的 SQL 执行
在上一篇文章<MySQL常见加锁场景分析>中,我们聊到行锁是加在索引上的,但是复杂的 SQL 往往包含多个条件,涉及多个索引,找出 SQL 执行时使用了哪些索引对分析加锁场景至关重要. 比 ...
- Spring IOC原理补充(循环依赖、Bean作用域等)
文章目录 前言 正文 循环依赖 什么是循环依赖? Spring是如何解决循环依赖的? 作用域实现原理以及如何自定义作用域 作用域实现原理 自定义Scope BeanPostProcessor的执行时机 ...
- tarjan算法求scc & 缩点
前置知识 图的遍历(dfs) 强连通&强连通分量 对于有向图G中的任意两个顶点u和v存在u->v的一条路径,同时也存在v->u的路径,我们则称这两个顶点强连通.以此类推,强连通分量 ...
- 【解读】TCP协议
本文内容如下: 1)TCP协议概念 2)TCP头部结构和字段介绍 3)TCP流量控制 滑动窗口 4)TCP拥塞控制 慢 ...
- 39 _ 队列5 _ 循环队列需要几个参数来确定 及其含义的讲解.swf
上面讲解都是循环队列,如果是链表实现的话就很简单,队列只有循环队列才比较复杂 此时队列中只存储一个有效元素3,当在删除一个元素的时候,队列为空,pFont向上移动,pFont等于pRear,但是此时p ...
- 关于MySQL事务和存储引擎常见FAQ
1.什么是事务? 事务就是「一组原子性的SQL查询」,或者说一个独立的工作单元.如果数据库引擎能够成功地对数据库应用该组查询的全部语句,那么就执行该组查询.如果其中有任何一条语句因为崩溃或其他原因无法 ...