首页 > 其他分享 >洛谷P2827题解

洛谷P2827题解

时间:2022-10-22 19:44:46浏览次数:91  
标签:node return 题解 P2827 void inline 洛谷 include ll

原题

P2827 [NOIP2016 提高组] 蚯蚓


思路概述

题意分析

给定整数 \(n,m,q,u,v,t\) 和一个数列 \(\{a\}\),进行 \(m\) 次操作如下:每次选取其中最大数 \(x\) 切分为 \([px],x-[px](p∈\frac{u}{v})\)。求每 \([\frac{m}{t}]\) 次切分的数大小与完成所有操作后第 \(t,2t,3t\dots\) 大的数字。

思路简述

每次对最大数进行操作,考虑用单调队列,但是在本题的数据规模下可能会超时。

分析题目后可以发现,只需要对初始数列按降序排序后就可以,就可以保证每次切分出的较大或较小段呈递减趋势,因此只需要开三个队列分别存储原始序列、切分后较大数的序列、切分后较小数的序列,然后模拟即可。


算法实现

关于长度计算

由于本题中每一个单位时间除被切分的数之外其他数都会增加 \(p\),因此每个数入队(包括存储原始序列的队列)时需要记录其入队时间以计算其即时长度。公式如下:

\[len_i=val_i+(time_{now}-time_{i})p \]

其中 \(len_i\) 为即时长度,\(val_i\) 为入队时的初始长度,\(time_{now},time_i\) 分别为当前时间与该数入队时间。

关于切分数细节问题

由于被切分数在当前时间段内长度不会增长,所以在考虑切分当前数字时对其时间的计算应该引入参数 \(time_{now}-1\) 而非 \(time_{now}\)。


AC code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<set>
#include<ctime>
#define ll long long
#define RL register long long
#define RN register node
using namespace std;
const ll maxn=7e6+10;
ll n,m,q,u,v,t;
ll a[maxn];
typedef struct
{
	ll val,tim;
	inline ll get_len(ll x){return val+(x-tim)*q;}
}node;
typedef struct
{
	ll fst,lst;
	node s[maxn];
	inline void init(void){fst=lst=0;memset(s,0,sizeof(s));return;}
	inline bool empty(void){return fst>=lst;}
	inline void push(node x){s[lst]=x;++lst;return;}
	inline void pop(void){++fst;return;}
	inline node front(void){return s[fst];}
}queue;
queue qr,mx,mn;
inline node max_node(ll ntm);
int main()
{
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin >> n >> m >> q >> u >> v >> t;
	for(RL i=1;i<=n;++i) cin >> a[i];
	sort(a+1,a+n+1,greater<ll>());
	for(RL i=1;i<=n;++i) qr.push((node){a[i],0});
	for(RL i=1,len,res;i<=m;++i)
	{
		RN temp=max_node(i);
		len=temp.get_len(i-1)*u/v;res=temp.get_len(i-1)-len;
		mx.push((node){max(len,res),i});
		mn.push((node){min(len,res),i});
		if(!(i%t)) printf("%lld ",temp.get_len(i-1));
	}
	putchar('\n');
	for(RL lim=n+m,i=1;i<=lim;++i)
	{
		RN temp=max_node(m);
		if(!(i%t)) printf("%lld ",temp.get_len(m));
	}
	return 0;
}
inline node max_node(ll ntm)
{
	RN x=(!qr.empty())?qr.front():(node){0,ntm},y=(!mx.empty())?mx.front():(node){0,ntm},z=(!mn.empty())?mn.front():(node){0,ntm};
	RL lx=x.get_len(ntm),ly=y.get_len(ntm),lz=z.get_len(ntm);
	if(lx>=ly && lx>=lz)
	{
		if(!qr.empty()) qr.pop();
		return x;
	}
	else if(ly>=lx && ly>=lz)
	{
		if(!mx.empty()) mx.pop();
		return y;
	}
	else
	{
		if(!mn.empty()) mn.pop();
		return z;
	}
}

标签:node,return,题解,P2827,void,inline,洛谷,include,ll
From: https://www.cnblogs.com/frkblog/p/16817136.html

相关文章

  • dremio 21 版本之后反射No File System scheme matches 问题解决
    实际属于一个老问题了,整理下,方便使用,主要是我们在使用反射的时候碰到的问题问题如下UnknownFormatConversionException:Conversion='Unknownformat(pdfs)conversio......
  • CodeForces-1143#C 题解
    正文♦时间复杂度:\(\mathcal{O}(n)\)思维题,不需要建树。设数组\(a\)记录每一个节点是否尊重它的父节点,数组\(b\)记录是否有节点尊重它,特别的,叶子节点必然不被尊重。......
  • [题解]如何求连续区间最大和
    给一个数列,有正有负,如何求最大的连续区间和?需要设f数组表示每个位置为结尾的最大区间和能否让f[i]等于f[i-1]+a[i]要看这样的f[i]是否大于零如果大于0,就说明它仍然可以......
  • 「题解」洛谷 P8529 [Ynoi2003] 赫露艾斯塔
    构造半平面莫队?/jk注意到对于一个半平面的直线,通过平移和旋转经过的点数,一定大于等于它们的对称差,因为对称差中的点会被经过奇数次,不在对称差中的点会被经过偶数次。那么......
  • ABC266 ~ 273 题解
    缺省源#pragmaGCCoptimize(3)#include<bits/stdc++.h>namespace//tofoldthatjunkcode{#definefilein(x){freopen(x".in","r",stdin);}#definefile(......
  • Fabricating Sculptures 题解
    草草地写一篇题解,废话不多说暴力要拼成“^”型,考虑\(DP\)令\(f_{i,j}\)表示,总共有\(i\)个积木,其中底座占了\(j\)个积木,也就是说你还有\(i-j\)个积木来拼底座的......
  • CF1716C Robot in a Hallway题解
    \(2000\)分的DP题。题意给定一个\(2\)行\(n\)列的网格。机器人初始坐标为\((0,1)\),每一秒都可以向四周移动。每个格子有解锁时间,在该时间之前机器人不可以进入该......
  • CF1045G 题解
    前言题目传送门!更好的阅读体验?和模版稍有不同的cdq分治。思路cdq是离线算法,所以我们可以先给\(x_i\)离散化一下。同时,记录下\((x_i-r_i)\)与\((x_i+r_i)......
  • 关于LoRa常见问题解答
    前面的文章中,小编有写过LORA技术低功耗广域网络,在大大小小的行业活动中,一直都是物联网的一个热门话题。LoRa主要在全球免费频段运行,包括433、868、915MHz等。后来有很多......
  • 「题解」Codeforces 1730F Almost Sorted
    给定一个长度为\(n\)的置换\(p\),以及一个正整数\(k\).对于一个置换\(q\),要求对于所有满足\(1\leqi<j\leqn\)的\(i,j\),有以下不等式成立:\[p_{q_i}\leqp_{q_j}+......