zoukankan      html  css  js  c++  java
  • 【Luogu】P2827蚯蚓(堆转队列)

    按照国际惯例先发题目链接‍

       woc从4月就开始做这sb题。最开始30分升到65分不管了,直到最近几天升到85分,再到今天AC。激动的心情自然是那些一遍就A或者一小时以内就A的神犇难以想象的。

       下面说说主要几个分段。

    # 35分

      按题意用堆模拟。每次暴力修改蚯蚓长度,于是get皮肤:TLE蓝。

    # 65分

       考虑到暴力修改消耗的时间复杂度过大,于是考虑偷懒。既然我们不能暴力增长已经存进堆的蚯蚓长度,那就剪短将要存进堆的蚯蚓长度。将目前蚯蚓增加的长度记为mark,从堆里取出来的蚯蚓长度+mark,要存进堆的蚯蚓长度-mark再-q。每次循环mark+=q。

    # 100分

       先忽略mark和q。蚯蚓肯定是越切越短,那我们还用堆干嘛?直接开三个队列存蚯蚓,第一个队列存输入的蚯蚓,对于切出来的每条蚯蚓,长的放第二个队列,短的放第三个队列。

    可以得到三个队列都是单调递减的。取出的蚯蚓从三个队列的队头取最大的。这样就转化为普通队列解法。

       代码如下

    #include<iostream>
    #include<cctype>
    #include<cmath>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    bool cmp(int a,int b){return a>b;}
    
    inline long long read(){
    long long num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        num=(num<<1)+(num<<3)+ch-'0';
        ch=getchar();
    }
    return num*f;
    }
    
    inline long long swap(long long a,long long b){long long temp=a;a=b;b=temp;}
    
    long long mark;
    
    long long n,m,q,u,v,t;
    long long que[10000000];
    long long f[10000000],d[10000000],fh=1,dh=1,ft,dt,qt=1;
    
    
    int main(){
    n=read();m=read();q=read();u=read();v=read();t=read();
    for(int i=1;i<=n;++i)que[i]=read();
    sort(que+1,que+n+1,cmp);
    for(int i=1;i<=m;++i){
        long long data=-1000000000;
        if(data<que[qt]&&qt<=n)data=que[qt];
        if(data<f[fh]&&ft-fh>-1)data=f[fh];
        if(data<d[dh]&&dt-dh>-1)data=d[dh];
       
        if(data==que[qt]&&qt<=n)qt++;
        else if(data==f[fh]&&ft-fh>-1)fh++;
        else if(dt-dh>-1)dh++;
       
        data+=mark;
        long long a=data*u/v;
        long long b=data-a;
        if(a<b)swap(a,b);
        f[++ft]=a-mark-q;
        d[++dt]=b-mark-q;
        if(!(i%t))printf("%lld ",data);
        mark+=q;
    }
    printf("
    ");
    for(int i=1;i<=n+m;++i){
        long long data=-1000000000;
        if(data<que[qt]&&qt<=n)data=que[qt];
        if(data<f[fh]&&ft-fh>-1)data=f[fh];
        if(data<d[dh]&&dt-dh>-1)data=d[dh];
       
        if(data==que[qt])qt++;
        else if(data==f[fh]&&ft-fh>-1)fh++;
        else if(dt-dh>-1)dh++;
       
        data+=mark;
        if(!(i%t))printf("%lld ",data);
    }
    return 0;
    }
  • 相关阅读:
    spinner下拉列表数据的添加
    inflater的简单使用
    json对象和json数组的简单转化
    线程之间的通讯
    根据网页地址获取页面内容
    ExtJS4 嵌套的border layout
    sql server Truncate清空表内数据,并对自增长列重置归零重新计算
    C# 将多个DLL和exe合成一个exe程序
    ExtJS4 border layout 左侧treePanel 中间 panel
    BugFree 3.0.4 一些操作
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/7467399.html
Copyright © 2011-2022 走看看