HDU 4325 Flowers 树状数组+离散化

Flowers

Problem Description

As is known to all, the blooming time and duration varies between different kinds of flowers. Now there is a garden planted full of flowers. The gardener wants to know how many flowers will bloom in the garden in a specific time. But there are too many flowers in the garden, so he wants you to help him.

Input

The first line contains a single integer t (1 <= t <= 10), the number of test cases.
For each case, the first line contains two integer N and M, where N (1 <= N <= 10^5) is the number of flowers, and M (1 <= M <= 10^5) is the query times.
In the next N lines, each line contains two integer S i and T i (1 <= S i <= T i <= 10^9), means i-th flower will be blooming at time [S i, T i].
In the next M lines, each line contains an integer T i, means the time of i-th query.

Output

For each case, output the case number as shown and then print M lines. Each line contains an integer, meaning the number of blooming flowers.
Sample outputs are available for more details.

Sample Input

2
1 1
5 10
4
2 3
1 4
4 8
1
4
6

Sample Output

Case #1:
0
Case #2:
1
2
1

分析

  我觉得你只要不傻,应该都能看出来这是个树状数组区间修改单点查询的板子题,但数据好像有点大,开数组是肯定开不下的,而最多就1e5朵花,所以在1e9之间有很多数字都被浪费掉了,所以使用离散化,离散化时记得将相同的数标记成一样的数字,还有询问也要离散化。

  然鹅这道题我很好奇的试了试,没有离散化直接让开1e5的数组然后跑树状数组,让我非常吃惊的是,它A了! HDU数据好水 出题人的意思肯定是让你用离散化,所以……看代码吧

  

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=1e5+5;
 6 int tr[N+5],a[N+5];
 7 struct Node{
 8     int id,x;
 9     bool operator <(const Node &A)const {
10         return x<A.x;//方便处理相等的情况
11     }
12 }p[N+5];
13 //树状数组开始
14 int lowbit(int x){
15     return x&(-x);
16 }
17 void Add(int x,int w){
18     while(x<=N){
19         tr[x]+=w;
20         x+=lowbit(x);
21     }
22 }
23 int Sum(int x){
24     int ans=0;
25     while(x){
26         ans+=tr[x];
27         x-=lowbit(x);
28     }
29     return ans;
30 }
31 //树状数组结束
32 int main(){
33     int n,cas=0;
34     scanf("%d",&n);
35     while(n--){
36         printf("Case #%d:\n",++cas);
37         int totn,totm;
38         scanf("%d%d",&totn,&totm);
39         totn*=2;
40         totm+=totn;
41         for(int i=1;i<=totm;i++){
42             scanf("%d",&p[i].x);
43             p[i].id=i;
44             //所有数据一次读完,并记录i的值,因为结构体排序后顺序被打乱
45         }
46         sort(p+1,p+totm+1);
47         a[p[1].id]=1;
48         int k=1;
49         for(int i=2;i<=totm;i++){
50             if(p[i].x==p[i-1].x)a[p[i].id]=k;//相等的值肯定也要离散成一样的呀
51             else a[p[i].id]=++k;
52         }
53         memset(tr,0,sizeof(tr));
54         for(int i=1;i<=totn;i+=2){
55             Add(a[i],1);
56             Add(a[i+1]+1,-1);
57         }
58         for(int i=totn+1;i<=totm;i++){
59             printf("%d\n",Sum(a[i]));
60         }
61     }
62     return 0;
63 }

猜你喜欢

转载自www.cnblogs.com/anyixing-fly/p/12431038.html