hdoj 5596 GTW likes gt 【思维】

GTW likes gt

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


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.
 


问题描述
从前,有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存活的个数。


思路:由于前面的删除会对后面的操作造成影响,可以考虑倒着推导。

设置M[0]存储j = from i to N中a[j]为0时,最大的b[j],同理M[1]。用new(b[i])表示经过Q此操作后b[i]的值。可以肯定的是对于任意一个a[k] 和 b[k],若M[a[k]^1] > new(b[k]),则第k个GT是不会存在的。对于M[0]和M[1],我们可以用O(N)的复杂度去维护,关键在于快速求出new(b[k])。因为b[1], b[2], ...,  b[ci]全部加一,相当于b[ci+1], b[ci+2], ..., b[N]全部减一,这样对于new(b[k]),我们只需要预处理1到k-1里发功的总次数c[k-1],new(b[k]) = b[k] - c[k-1]。这个c[]的信息可以用O(N)的复杂度预处理得到。

总时间复杂度O(N)。


AC代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define MAXN (50000+1)
#define MAXM (5000000000)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
using namespace std;
int a[MAXN], b[MAXN], c[MAXN];
int M[2];
int main()
{
    int t; Ri(t);
    W(t)
    {
        int N, Q; Ri(N); Ri(Q);
        for(int i = 1; i <= N; i++)
            Ri(a[i]), Ri(b[i]);
        CLR(c, 0); int x;
        for(int i = 1; i <= Q; i++)
            Ri(x), c[x]++;
        for(int i = 1; i <= N; i++)
            c[i] += c[i-1];
        int ans = N;
        M[0] = M[1] = -INF;
        for(int i = N; i >= 1; i--)
        {
            b[i] -= c[i-1];
            if(b[i] < M[a[i]^1]) ans--;
            M[a[i]] = max(M[a[i]], b[i]);
        }
        Pi(ans);
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值