• [NOIP2016提高组]蚯蚓


    题目:UOJ#264、洛谷P2827、Vijos P2007。

    题目大意:给你$n$条蚯蚓的初始长度,每秒把一条最长的蚯蚓(设长度为x)切成长度$lfloor px floor$和$x-lfloor px floor$的两条蚯蚓(p为满足$0<p<1$的有理数,$p=frac{u}{v}$,u和v输入给出)(注意切完后长度为0也要保留),切完后所有蚯蚓(不包括当前切出的两条)长度增加$q$。一共切$m$秒。需要输出第$t$秒,第$2t$秒,第$3t$秒……第$lfloor frac{m}{t} floor t$秒所切的蚯蚓的长度是多少,以及$m$秒后第$t$长,第$2t$长,第$3t$长……第$lfloorfrac{n+m}{t} floor t$长的蚯蚓的长度是多少。

    解题思路:首先我们给蚯蚓从大到小排序。然后可以发现,每次切出来的蚯蚓中,长的那写按切的顺序形成非上升序列,短的那些也如此。那么我们维护3个单调队列即可(原始蚯蚓也算一个单调队列),每次找三个队列队首元素最大的那个,把这个蚯蚓切掉,然后分别插入两个单调队列中。最后也按照这样每次找出最大的,按要求把该输出的输出即可。由于最后有$n+m$只蚯蚓,所以这样的时间复杂度$O(n+m)$。

    UOJ的Extra Test会卡你$p$的精度,要用long double。

    C++ Code:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cctype>
    using namespace std;
    int y[7200005],d[7200005],x[7200005],ly,ry,ld,rd,lx,rx,n,m,q,u,v,t,pl,bufpos;
    long double p;
    char buf[30000000];
    inline void init(){
        bufpos=0;
        buf[fread(buf,1,30000000,stdin)]='';
    }
    inline int readint(){
        int p=0;
        for(;!isdigit(buf[bufpos]);bufpos++);
        for(;isdigit(buf[bufpos]);bufpos++)
        p=(p<<3)+(p<<1)+buf[bufpos]-'0';
        return p;
    }
    bool com(int a,int b){return a>b;}
    int main(){
    	init();
    	memset(y,129,sizeof y);
    	n=readint(),m=readint(),q=readint(),u=readint(),v=readint(),t=readint();
    	p=(long double)u/v;
    	for(int i=1;i<=n;++i)y[i]=readint();
    	sort(y+1,y+n+1,com);
    	ly=ld=lx=1;
    	ry=n;
    	rd=rx=pl=0;
    	memset(d,129,sizeof d);
    	memset(x,129,sizeof x);
    	for(int i=1;i<=m;++i){
    		int yb=y[ly]+pl,db=d[ld]+pl,xb=x[lx]+pl;
    		pl+=q;
    		if(db>xb){
    			if(db>yb){
    				if(i%t==0)printf("%d ",db);
    				int a=(int)(db*p);
    				int b=db-a;
    				if(a<b)swap(a,b);
    				d[++rd]=a-pl;
    				x[++rx]=b-pl;
    				++ld;
    			}else{
    				if(i%t==0)printf("%d ",yb);
    				int a=(int)(yb*p);
    				int b=yb-a;
    				if(a<b)swap(a,b);
    				d[++rd]=a-pl;
    				x[++rx]=b-pl;
    				++ly;
    			}
    		}else{
    			if(xb>yb){
    				if(i%t==0)printf("%d ",xb);
    				int a=(int)(xb*p);
    				int b=xb-a;
    				if(a<b)swap(a,b);
    				d[++rd]=a-pl;
    				x[++rx]=b-pl;
    				++lx;
    			}else{
    				if(i%t==0)printf("%d ",yb);
    				int a=(int)(yb*p);
    				int b=yb-a;
    				if(a<b)swap(a,b);
    				d[++rd]=a-pl;
    				x[++rx]=b-pl;
    				++ly;
    			}
    		}
    	}
    	printf("
    ");
    	int ct=0;
    	while(ly<=ry||ld<=rd||lx<=rx){
    		++ct;
    		int yb=y[ly]+pl,db=d[ld]+pl,xb=x[lx]+pl;
    		if(db>xb){
    			if(db>yb){
    				if(ct%t==0)printf("%d ",db);
    				++ld;
    			}else{
    				if(ct%t==0)printf("%d ",yb);
    				++ly;
    			}
    		}else{
    			if(xb>yb){
    				if(ct%t==0)printf("%d ",xb);
    				++lx;
    			}else{
    				if(ct%t==0)printf("%d ",yb);
    				++ly;
    			}
    		}
    	}
    	printf("
    ");
    	return 0;
    }
    
  • 相关阅读:
    [转载]TFS测试管理
    [转载]TFS发送邮件提醒功能
    [转载]TFS与Project、Excel同步
    [转载]TFS源代码管理8大注意事项
    [转载]TFS源代码管理
    [转载]项目风险管理七种武器之结语
    [转载]项目风险管理七种武器-拳头
    刷新SqlServer所有视图元数据的存储过程
    MSSQL 触发器 暂停 和 启动
    给 Easyui Datagrid 扩展方法
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/7517155.html
Copyright © 2020-2023  润新知