NOIP2016 蚯蚓

题目传送门

刚看到这道题:这题直接用堆+模拟不就可以了(并没有认真算时间复杂度)

于是用priority_queue水到了85分…… (STL大法好)

天真的我还以为是常数问题,于是疯狂卡常……(我是ZZ)

直到我下了组数据,结果它跑了……跑了……10s (这叫我怎么卡常)

OK,闲聊到次结束,接下来说正解


其实这道题并不需要用堆,因为我们可以蚯蚓其实是满足单调性的,因为后切的蚯蚓一定要比先切的短,所以堆是不必要的,我们只用三个队列,分别记录没被切的蚯蚓、被切了的短的蚯蚓、被切了的长的蚯蚓,每次把三个队列的队头取出来比较,切掉最长的,再分别入队。

时间复杂度:\(O(n+m)\)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int read(){
    int k=0,f=1; char c=getchar();
    for(;c<'0'||c>'9';c=getchar())
      if(c=='-') f=-1;
    for(;c>='0'&&c<='9';c=getchar())
      k=(k<<3)+(k<<1)+c-48;
    return k*f;
}
double p;
int qy[100010],cut1[10000010],cut2[10000010];
int h=1,ta,h1=1,t1,h2=1,t2;
bool cmp(int x,int y){
    return x > y;
}
int main(){
    //freopen("hhh.in","r",stdin);
    //freopen("hhh.out","w",stdout);
    int n=read(),m=read(),q=read(),u=read(),v=read(),t=read();
    memset(cut1,-127,sizeof(cut1));
    memset(cut2,-127,sizeof(cut2));
    memset(qy,-127,sizeof(qy));
    p=(double)u/(double)v; ta=n;
    for(int i=1;i<=n;i++) qy[i]=read();
    sort(qy+1,qy+n+1,cmp);
    for(int i=1;i<=m;i++){
    	int maxn=-2147483647; bool flag=0;
    	if(qy[h]>=cut1[h1]&&qy[h]>=cut2[h2]&&h<=ta){
    		maxn=qy[h]+(i-1)*q; h++; flag=1;
    		//printf("%d %d\n",h,ta);
        }
        if(cut1[h1]>=cut2[h2]&&cut1[h1]>=qy[h]&&!flag&&h1<=t1){
            maxn=cut1[h1]+(i-1)*q; h1++; flag=1;
            //printf("%d %d\n",h1,t1);
        }
        if(cut2[h2]>=cut1[h1]&&cut2[h2]>=qy[h]&&!flag&&h2<=t2){
            maxn=cut2[h2]+(i-1)*q; h2++; flag=1;
            //printf("%d %d\n",h2,t2);
        }
        //printf("%d %d %d\n",qy[h],cut1[h1],cut2[h2]);
        if(i%t==0) printf("%d ",maxn);
        int k=maxn*p;
        cut1[++t1]=k-i*q; cut2[++t2]=maxn-k-i*q;
    }
    printf("\n");
    for(int i=1;i<=n+m;i++){
    	int maxn=-2147483647; bool flag=0;
    	if(qy[h]>=cut1[h1]&&qy[h]>=cut2[h2]&&h<=ta){
    		maxn=qy[h]+m*q; h++; flag=1;
        }
        if(cut1[h1]>=cut2[h2]&&cut1[h1]>=qy[h]&&!flag&&h1<=t1){
            maxn=cut1[h1]+m*q; h1++; flag=1;
        }
        if(cut2[h2]>=cut1[h1]&&cut2[h2]>=qy[h]&&!flag&&h2<=t2){
            maxn=cut2[h2]+m*q; h2++; flag=1;
        }
        if(i%t==0)
          printf("%d ",maxn);
    }
    return 0;
}
posted @ 2019-11-13 21:41  MorsLin  阅读(75)  评论(0编辑  收藏  举报