蚯蚓,题解

题目找链接

题意:

  非常清晰的题意,就不再多说了。

分析:

  看到这一题,其实思路一下子就有了,先从最暴力的开始吧:我们每次找一个最大拆开,然后别的都加上,也就是直接模拟,首先,这样的正确性是没问题的,但是时间不行,所以我们,要想别的办法,只招最大,大家应该很容易想到优先队列,用优先队列直接模拟的复杂度还不如暴力,但我们可以优化:

  想这样一个问题,这里有一些数字a1,a2,a3,a4,a5。。。你要使每一个数增加da(不是线段树。。。),我们要怎么操作呢,其实我们不用操作,我们找一个基数,让基数加da,然后查询每个元素的时候加上这个基数就好了,如果有不更新的,那么我们可以直接减去da(当然这样转换是因为不减的比减的少),然后我们就可以再次模拟了,但是,tle,tle,tle。。。其实nlogn的常熟小一点是可以过的,但是这里真的过不了,虽然vjudge时限是10000ms,但是这并不能让我们过掉,当然,手写堆我也试了,一样tle。

  其实想到这里然后就好办了,我们的log其实很多都是浪费的复杂度,我们想一想,n比较小,我们对n个数进行排序之后,就不再排序了,开三个队列,分别存n个数,某一半的长度,另一半的长度,为什么不用排序了呢?虽然操作之后每个蚯蚓都会变长,但是我们加在了基数上,所有完全可以保证三个队列一直单增。于是这一题就好解决了。

  然后,还有:如果用stl的话,队列里开long long会tle(stl常数有多大啊。。。)所以开int,当然,q才200,不会爆掉int。但是答案可不一定在int内。

  最后就是代码。

#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn=1e5+10;
int a[maxn];
queue<int> qu1;
queue<int> qu2;
queue<int> qu3;
int Top(){
    int qu11,qu22,qu33;
    if(qu1.empty())
        qu11=-1e9;
    else
        qu11=qu1.front();
    if(qu2.empty())
        qu22=-1e9;
    else
        qu22=qu2.front();
    if(qu3.empty())
        qu33=-1e9;
    else
        qu33=qu3.front();
    if(qu11>qu22&&qu11>qu33)
        return qu11;
    else if(qu22>qu33)
        return qu22;
    else
        return qu33;
}
void Pop(){
    int qu11,qu22,qu33;
    if(qu1.empty())
        qu11=-1e9;
    else
        qu11=qu1.front();
    if(qu2.empty())
        qu22=-1e9;
    else
        qu22=qu2.front();
    if(qu3.empty())
        qu33=-1e9;
    else
        qu33=qu3.front();
    if(qu11>qu22&&qu11>qu33)
        qu1.pop();
    else if(qu22>qu33)
        qu2.pop();
    else
        qu3.pop();
}
int main(){
    int n,m;
    int q,u,v,t;
//    freopen("P2827_2(1).in","r",stdin);
//    freopen("ouou.out","w",stdout);
    scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
    long long Ha=0;
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    sort(a+1,a+1+n);
    for(int i=n;i>=1;i--)
        qu1.push(a[i]);
    for(int i=1;i<=m;i++){
        long long x=Top()+Ha;
        Pop();
        int x1=u*x/v-Ha-q;
        int x2=x-u*x/v-Ha-q;
        qu2.push(x1);
        qu3.push(x2);
        if(i%t==0)
            printf("%lld ",x);
        Ha+=q;
    }
    printf("\n");
    for(int i=1;i<=m+n;i++){
        if(i%t==0)
            printf("%lld ",Top()+Ha);
        Pop();
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/wish-all-ac/p/12714974.html