HDU 5596 GTW likes gt(巧用multiset)——BestCoder Round #66(div.1 div.2)

GTW likes gt

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 0    Accepted Submission(s): 0


Problem Description
Long long ago, there were  n  adorkable GT. Divided into two groups, they were playing games together, forming a column. The  ith   GT would randomly get a value of ability  bi . At the  ith   second, the  ith   GT would annihilate GTs who are in front of him, whose group differs from his, and whose value of ability is less than his.

In order to make the game more interesting, GTW, the leader of those GTs, would emit energy for  m  times, of which the  ith   time of emitting energy is  ci . After the  ci  second,  b1,b2,...,bci      would all be added 1.

GTW wanted to know how many GTs would survive after the  nth  second.
 

Input
The first line of the input file contains an integer  T(5) , which indicates the number of test cases.

For each test case, there are  n+m+1  lines in the input file.

The first line of each test case contains 2 integers  n  and  m , which indicate the number of GTs and the number of emitting energy, respectively. (1n,m50000)

In the following  n  lines, the  ith  line contains two integers  ai  and  bi , which indicate the group of the  ith  GT and his value of ability, respectively.  (0ai1,1bi106)

In the following  m  lines, the  ith  line contains an integer  ci , which indicates the time of emitting energy for  ith  time.
 

Output
There should be exactly  T  lines in the output file.

The  it   line should contain exactly an integer, which indicates the number of GTs who survive.
 

Sample Input
   
   
   
   
1 4 3 0 3 1 2 0 3 1 1 1 3 4
 

Sample Output
   
   
   
   
3
Hint
After the first seconds,b1=4,b2=2,b3=3,b4=1 After the second seconds,b1=4,b2=2,b3=3,b4=1 After the third seconds,b1=5,b2=3,b3=4,b4=1,and the second GT is annihilated by the third one. After the fourth seconds,b1=6,b2=4,b3=5,b4=2 ci is unordered.
 

Source
BestCoder Round #66 (div.2)
 

/************************************************************************/

附上该题对应的中文题

GTW likes gt

 
 
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 131072/131072 K (Java/Others)
问题描述
从前,有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存活下来。
输入描述
第一行只有一个整数T(T\leq 5)T(T5),表示测试数据组数。
第二行有两个整数n,mn,m。表示GT的个数和GTW发功的次数。(1\leq n \leq 50000,1\leq m\leq 500001n50000,1m50000)
第三到n+2n+2行,每行有两个整数a_i,b_iai,bi,表示第ii只GT在哪个组和他的能力值 (0\leq a[i]\leq 1,1\leq b[i]\leq 10^6)(0a[i]1,1b[i]106)n+3n+3行到第n+m+2n+m+2行,每行有一个整数c_ici,表示GTW第ii次发功的时间。1\leq c[i]\leq n1c[i]n
输出描述
总共TT行,第ii行表示第ii组数据中,GT存活的个数。
输入样例
1
4 3
0 3
1 2
0 3
1 1
1
3
4
输出样例
3
Hint
11秒后 能力值为4\ 2\ 3\ 14 2 3 122秒后 能力值为4\ 2\ 3\ 14 2 3 133秒后 能力值为5\ 3\ 4\ 15 3 4 1,第22只GT被第33只GT消灭掉了
第44秒后 能力值为6\ 4\ 5\ 26 4 5 2
c_ici并不是有序的
/****************************************************/

出题人的解题思路:

GTW likes gt

首先这道题有一个很显然的O(n*logn)O(nlogn)的做法,直接区间加,求区间最大值即可。 但是此题还有一个O(n)O(n)的做法。我们发现b_1,b_2,...,b_xb1,b2,...,bx都加11就相当于b_{x+1},b_{x+2},...,b_nbx+1,bx+2,...,bn都减11。然后我们可以倒着做,记一下最大值,如果遇到了修改操作,就把最大值减11,然后判断一下这个人会不会被消灭掉,然后再更新一下最大值。

对于ci秒的发功,b1,b2,……,bci都会增加1,那就相当于bci+1,bci+2,……bn都减少了1,我们只要模拟每一秒的状态即可,此过程中我们需要记录当前时间t之前已经发功的次数,multiset用于记录t之前GT能力值,然后每秒我们删去multiset里比当前GT能力值小的数,那最终留下的就是存活下来的,需要注意的一点是同一秒可以发功多次,就因为这个,一开始WA了一次,但是没想到最后admin居然提醒了,然而我已经AC了
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 50005;
const int M = 710;
const int inf = 1000000000;
const int mod = 1000000007;
int a[N],b[N];
int c[N];
multiset<int> s1,s2;
multiset<int>::iterator it;
int main()
{
    int t,n,m,i,k,x,sum1,sum2;
    scanf("%d",&t);
    while(t--)
    {
        s1.clear();s2.clear();
        memset(c,0,sizeof(c));
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
            scanf("%d%d",&a[i],&b[i]);
        for(i=0;i<m;i++)
        {
            scanf("%d",&x);
            c[x]++;
        }
        sum1 = sum2 = 0;
        for(i=1,k=0;i<=n;i++)
        {
            b[i] -= k;
            if(a[i]==0)
            {
                if(!s2.empty())
                    for(it=s2.begin();it!=s2.end();)
                        if(b[i]> *it){

                            s2.erase(it),sum2--;
                            it = s2.begin();
                        }
                        else
                            break;
                s1.insert(b[i]);
                sum1++;
            }
            else if(a[i]==1)
            {
                if(!s1.empty())
                    for(it=s1.begin();it!=s1.end();)
                        if(b[i]> *it){
                            s1.erase(it);
                            sum1--;
                            it = s1.begin();
                        }
                        else
                            break;
                s2.insert(b[i]);
                sum2++;
            }
            if(c[i])
                k += c[i];
        }
        printf("%d\n",sum1+sum2);
    }
    return 0;
}
菜鸟成长记

你可能感兴趣的:(ACM,STL)