Hdu 4325 Flowers 树状数组+离散化
2017-03-22 17:00
183 查看
Flowers
Time Limit : 4000/2000ms (Java/Other) Memory Limit : 65536/65536K (Java/Other)
Total Submission(s) : 2 Accepted Submission(s) : 2
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
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 flowersin 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 Si and Ti (1 <= Si <= Ti <= 10^9), means i-th flower will be blooming at time [Si, Ti].
In the next M lines, each line contains an integer Ti, 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
题意:不同的花在不同时间段开放,问某个时间段有多少花开着。
思路:看题目我们就知道要把时间作为线段,通过输入的开放时间来更新区间,但是题目给出的时间单位时1~1^9,数组开不了那么大,所以得用离散化来解决这个问题。 离散化:(把很大的时间区间用比较小的值来保存,比如 100 25 300 40 ,就可以分别保存为3 1 4 2。这样就可以节省空间了,由于题目给的n时50000,所以时间最多最多只能分这么多区间,所以数组开500000就可以了。
把时间分区间的方法:首先每个点用结构体存,存它是第几朵花和它的时间点,然后先按时间从小到大排,然后给它一个id,用来时间分区,并且同时把你后面输入的查询时间也用相同的方法保存。然后用树状数组把点按花朵编号的顺序存进去,但给的时间是离散化后的时间,最后给出答案就好了。
代码如下:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; #define maxn 500000 int sum1[maxn],sum2[maxn],id; struct Node{ //点的结构体 int num,pos; }node[maxn]; int cmp(const Node &a,const Node &b){ return a.num < b.num; //升序排列 } int getSum(int x){ // 统计区间数值 int sum = 0; while(x > 0){ sum += sum1[x]; x -= x & -x; } return sum; } void update(int pos,int num){ // 把sum2里的数,就是时间点扔进来,把这个时间点之后的区间更新 while(pos <= id){ sum1[pos] += num; pos += pos & -pos; } } int main(){ int n,m,t,Case = 1; scanf("%d",&t); while(t--){ printf("Case #%d:\n",Case++); scanf("%d %d",&n,&m); int tn = n * 2; int tm = tn + m; for(int i = 0;i < tm;i++){ scanf("%d",&node[i].num); node[i].pos = i; } sort(node,node + tm,cmp); //把所有输入进来的时间点按从小到大排序,然后分成小区间存sum2里 id = 1; sum2[node[0].pos] = id; //第一个点就存1 for(int i = 1;i < tm;i++){ //把数离散化分成小的存在sum2里面 if(node[i].num == node[i - 1].num){ //若这个点与前一个点时间相同,则存同一个区间 sum2[node[i].pos] = id; }else{ //不相同则存下一个区间 sum2[node[i].pos] = ++id; } } memset(sum1,0,sizeof(sum1)); for(int i = 0;i < tn - 1;i++){ update(sum2[i++],1); //把前数扔进来,后面区间加一 update(sum2[i] + 1, -1); //后数扔进来,后面巨剑减一 } for(int i = tn;i < tm;i++){ printf("%d\n",getSum(sum2[i])); //sum2[i]指的时那个时间点的离散化后的时间点,找到这个时间点里存的值。 } } return 0; }
相关文章推荐
- hdu 4325 Flowers 离散化+线段树 多校联合赛(三) 第六题
- HDU 4325 Flowers
- HDU 4325 - Flowers
- HDU 4325 Flowers(树状数组+离散化)
- HDU 4325 Flowers (线段树+离散化)
- HDU 4325 Flowers(树状数组+离散化)
- hdu 4325 Flowers
- 【HDU - 4325 】Flowers 【树状数组+离散化】
- HDU 4325 Flowers(树状数组)
- HDU 4325 Flowers(二分查找求上界)
- hdu 4325 Flowers(区间离散化)
- HDU 4325-Flowers(线段树+离散化)
- HDU4325——二分——Flowers
- hdu 4325 Flowers (树状数组+离散化)
- hdu -4325-Flowers(离散化 线段树)
- hdu 4325 Flowers(呕心沥血)
- hdu 4325 Flowers
- hdu 4325 Flowers
- hdu 4325 Flowers(线段树+哈希散列)
- hdu 4325 Flowers(线段树+离散化)