[luogu-2877]noip2016-day2-T2 蚯蚓 题解

题目传送门
题意解析:题目给了你n条蚯蚓,然后让你每次找出一条长度最长蚯蚓,然后把它切断,而且每次切断的位置都会告诉你(每次切开都是按照一个比例来的)。然后蚯蚓就会向你所知道的一样变成两节(为什么是瞬间恢复的?而且长度为0也是一种特殊的存在,居然还不死)。最后这次砍断结束后,除了这次被砍断的蚯蚓,都会长长q的长度(长得真快)。


My opinion:虽然这题有很多的槽点,但是我们还是得去做是不是,因为每次蚯蚓都会变长,所以我们是不可能直接出答案的。然后我就想到了,既然是每次找出最大值,那么是不是可以用堆,然而n有七百万,所以堆明显要被卡常(更别说我这种还把堆写错,强行从log变成n^2的人了)。所以只能使用O(n)处理这个问题,这样的话,我们只有一个办法了那就是单调队列,我们每次维护一个初始队列,把切开的两个分别在放在两个队列里。
总结:
1、输入。
2、单调队列维护。
3、输出。


神奇的代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=a;i>=n;i--)
#define Clear(a,x) memset(a,x,sizeof(a))
#define ll long long
#define INF 2000000000
#define eps 1e-8
#define db double
using namespace std;
ll read(){
    ll x=0,f=1;
    char ch=getchar();
    while (ch<'0'||ch>'9') f=ch=='-'?-1:f,ch=getchar();
    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
const int maxn=100005,maxm=7000005;
int n,m,q,u,v,t;
int x[maxn],y[maxm],z[maxm];
int tx,ty,tz,wy,wz,mark;
bool cmp(int a,int b){
    return a>b;
}
int work(int i,int s){
    int k=0,tmp=-INF;
    if (tx<n&&x[tx+1]+mark>tmp){
        tmp=x[tx+1]+mark;
        k=1;
    }
    if (ty<wy&&y[ty+1]+mark>tmp){
        tmp=y[ty+1]+mark;
        k=2;
    }
    if (tz<wz&&z[tz+1]+mark>tmp){
        tmp=z[tz+1]+mark;
        k=3;
    }
    if (i%t==0&&(i/t!=s/t)) printf("%d ",tmp);
        else if (i%t==0) printf("%d",tmp);
    if (k==1) tx++;
    if (k==2) ty++;
    if (k==3) tz++;
    return tmp;
}
int main(){
    n=read(),m=read(),q=read(),u=read(),v=read(),t=read();
    rep(i,1,n) x[i]=read();
    sort(x+1,x+n+1,cmp);
    rep(i,1,m){
        int tmp=work(i,m);
        int X=floor((db)tmp*u/v);
        int Y=tmp-X;
        mark+=q;
        y[++wy]=X-mark;
        z[++wz]=Y-mark;
    }
    puts("");
    rep(i,1,n+m)
        work(i,n+m);
    puts("");
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值