BC66 GTW likes gt


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 ith 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,$b_1=4,b_2=2,b_3=3,b_4=1$ After the second seconds,$b_1=4,b_2=2,b_3=3,b_4=1$ After the third seconds,$b_1=5,b_2=3,b_3=4,b_4=1$,and the second GT is annihilated by the third one. After the fourth seconds,$b_1=6,b_2=4,b_3=5,b_4=2$ $c_i$ is unordered.


題解:

此題注意不要被c[i]沒有順序坑了,其實c[i]的作用就是

將1-c[i]都加1,保存到數組裏面統計次數就行了,

O(n)的做法可以先直接算出加上所有c[i]的結果後

(因爲如果第i秒的能力值比前面不是同一組的能力值大,

那麼就會一直比前面那個數大,因爲i秒後,他們加的次數是一樣的),

在統計不需要被刪除的個數。

#include <stdio.h>
#include <string.h>
const int maxn = 55555;
int add[maxn], sum[maxn], mx[2][maxn], a[maxn], b[maxn];
void print ( int n )
{
    for ( int i = 1; i <= n; i ++ )
        printf ( "%d ", b[i] );
    printf ( "\n" );
}
/*
此題可以先算出答案再計算:
因爲後面的數變大時,前面的數也會變大,如果第i秒有個數比前面不是同一組的數
大,那麼它就會一直比前面那個數大
*/
inline int Max ( int a, int b )
{
    return a > b ? a : b;
}
int main ( )
{
    int T, n, m, time, ans;
    scanf ( "%d", &T );
    while ( T -- )
    {
        memset ( add, 0, sizeof ( add ) );
        memset ( sum, 0, sizeof ( sum ) );
        memset ( mx, 0, sizeof ( mx ) );
        scanf ( "%d%d", &n, &m );
        for ( int i = 1; i <= n; i ++ )
            scanf ( "%d%d", &a[i], &b[i] );
        for ( int i = 0; i < m; i ++ )
        {
            scanf ( "%d", &time );
            add[ time ] ++; //前time個需要加
        }
        for ( int i = n; i >= 1; i -- ) //注意逆序
        {
            sum[i] = sum[i+1]+add[i];
            b[i] = b[i]+sum[i]; //將最後的值算出來
        }
        //print ( n );
        for ( int i = n; i >= 1; i -- )
        {
            mx[ a[i] ][i] = Max ( b[i], mx[ a[i] ][i+1] );  //保存01組i-n的最大值
            mx[ a[i]^1 ][i] = mx[ a[i]^1 ][i+1];    //開始少了這個
        }
        ans = 0;
        for ( int i = 1; i <= n; i ++ )
            if ( b[i] >= mx[ a[i]^1 ][i+1] )    //比不是同一組的最大值還大就不會被刪除
                ans ++;
        printf ( "%d\n", ans );
    }
    return 0;
}


發佈了20 篇原創文章 · 獲贊 21 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章