HDU 5596 GTW likes gt

题意:

从前,有nn只萌萌的GT,他们分成了两组在一起玩游戏。他们会排列成一排,第ii只GT会随机得到一个能力值b_ibi。在第ii秒的时候,第ii只GT可以消灭掉所有排在他前面的和他不是同一组的且能力值小于他的GT。
为了使游戏更加有趣,GT的首领GTW会发功mm次,第ii次发功的时间为c_ici,则在第c_ici秒结束后,b_1,b_2,...,b_{c_i}b1,b2,...,bci都会增加1。
现在,GTW想知道在第nn秒之后,会有几只GT存活下来。

这个题就是凸显出了自己智商低的一个典范,我一直在想前面的怎么加,不能一直循环相加,后来终于想明白了可以先把前面的统一加起来,是不影响后面的,因为在当前那秒的时候,你只需要知道前面的数是多少就是了,你当前这个数加了多少,你前面的数就该加多少,所以不影响。我只需要倒着走就行了。

后来还是没有搞出来,看了官方题解,我就发现我是傻了,都快要做出来了。他有一个转换,其实不算和,就算减的,前面都加1,相当于后面都减一,我就可以顺着做了。郁闷


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<vector>
#include<set>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m;
int a[50005];
int b[50005];
int c[50005];

int main()
{

    int t;
    scanf("%d",&t);
    while(t--)
    {
        priority_queue<int,vector<int>,greater<int> >q1;//相当于从小到大
        priority_queue<int,vector<int>,greater<int> >q0;<span style="font-family: Arial, Helvetica, sans-serif;">//相当于从小到大</span>

        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
            scanf("%d%d",&a[i],&b[i]);
        memset(c,0,sizeof(c));
        for(int i=1;i<=m;i++)
        {
            int x;
            scanf("%d",&x);
            c[--x]++;
        }
        int cnt=0;
        int ans=0;
        for(int i=0;i<n;i++)
        {
            b[i]-=cnt;减去之前的发功次数
            printf("%d %d\n",b[i],cnt);
            cnt+=c[i];//累加当前是否发功,发功几次
            if(a[i]==0)//检查当前他可以打死不是和他一个队伍,并且比他小的
            {
                while(!q1.empty()&&q1.top()<b[i])
                {
                    //printf("%d\n",q1.top());
                    ans++;//记下个数
                    q1.pop();
                }
                q0.push(b[i]);
            }
            else
            {
                while(!q0.empty()&&q0.top()<b[i])
                {
                    //printf("%d\n",q0.top());
                    ans++;
                    q0.pop();
                }
                q1.push(b[i]);
            }
        }
        printf("%d\n",n-ans);
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值