NOIP2016 提高组Day2 T2蚯蚓(蓝书刷题记录)

问题描述:给定一个长度为n的序列,对于每一个时刻,从序列中选出最大值裂成两个数
xq 和x - xq 其中 q 等于两个给定 u v 的商。 问过了时间 m 之后 序列的情况 (从大到小排序) 以及每隔 t 时刻对哪个数下手了。
题解:因为大的数裂开一定比小的数裂开的大,时间其实对大小的影响是没有的。
开三个 队列 A B C 。
其中A 存的是开始的序列 B 存的是 裂开后 xq 部分。 C 存的是 x-xq 部分。 证明三个队列的单调性可以证明(借其他人的博客??)
每次从三个队列中选出最大值 裂开 插入 B C 中
注意插入的是没有随时间变化的长度。因为所有的增长都可以最后统一处理。
详见代码:

#include<bits/stdc++.h>
#define ll long long 
 using namespace std;
queue<ll>A,B,C;
int n,m,q,u,v,t,a[100010];
bool myc(int x,int y) {return x>y;}
ll find(int T)
{
   ll X=-1,Y=-1,Z=-1;
   if(A.size()) X=A.front()+(ll)T*q; 
   if(B.size()) Y=B.front()+(ll)T*q; 
   if(C.size()) Z=C.front()+(ll)T*q;
   if(X>=Y&&X>=Z) {A.pop(); return X;} 
   if(Y>=X&&Y>=Z) {B.pop(); return Y;} 
   if(Z>=X&&Z>=Y) {C.pop(); return Z;} 
}
int main()
{	
  cin>>n>>m>>q>>u>>v>>t;
  for(int i=1;i<=n;i++) scanf("%d",&a[i]);
  sort(a+1,a+n+1,myc);
  for(int i=1;i<=n;i++) A.push((ll)a[i]);
  for(int i=1;i<=m;i++)
  { 
    ll x=find(i-1);
  	if(i%t==0) printf("%lld ",x);
  	B.push(1LL*x*u/v-i*q);
  	C.push(x-1LL*x*u/v-i*q);
  }
  puts("");
  for(int i=1;i<=n+m;i++)
  {
    ll x=find(m);
    if(i%t==0) printf("%lld ",x);
  }
  return 0;	
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值