FlowersTime Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2497 Accepted Submission(s): 1239
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
Sample Output
|
题意:有n朵花,已经给出每朵花的开花时间[s, e]。现在有m次查询,对查询值x,输出在时间点x开花的个数。
思路:先离散化开花的时间区间,然后就是线段树区间更新 + 单点查询
AC代码:
#include <cstdio> #include <cstring> #include <algorithm> #define MAXN 200000+10 #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; struct Tree { int l, r; int len; int sum; int lazy; }; Tree tree[MAXN<<2]; void build(int o, int l, int r) { tree[o].l = l, tree[o].r = r; tree[o].len = r - l + 1; tree[o].sum = tree[o].lazy = 0; if(l == r) return ; int mid = (l + r) >> 1; build(lson); build(rson); } void PushDown(int o) { if(tree[o].lazy) { tree[ll].lazy += tree[o].lazy; tree[rr].lazy += tree[o].lazy; tree[ll].sum += tree[o].lazy * tree[ll].len; tree[rr].sum += tree[o].lazy * tree[rr].len; tree[o].lazy = 0; } } void PushUp(int o) { tree[o].sum = tree[ll].sum + tree[rr].sum; } void update(int L, int R, int o) { if(L <= tree[o].l && R >= tree[o].r) { tree[o].lazy += 1; tree[o].sum += tree[o].len; return ; } PushDown(o); int mid = (tree[o].l + tree[o].r) >> 1; if(R <= mid) update(L, R, ll); else if(L > mid) update(L, R, rr); else { update(L, mid, ll); update(mid+1, R, rr); } PushUp(o); } int query(int o, int pos) { if(tree[o].l == tree[o].r) return tree[o].sum; PushDown(o); int mid = (tree[o].l + tree[o].r) >> 1; if(pos <= mid) return query(ll, pos); else return query(rr, pos); } int rec[MAXN]; int s[MAXN], e[MAXN]; int Q[MAXN]; int Find(int l, int r, int val) { while(r >= l) { int mid = (l + r) >> 1; if(rec[mid] == val) return mid; else if(rec[mid] > val) r = mid - 1; else l = mid + 1; } return -1; } int main() { int t, k = 1; int n, m; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &m); int p = 1; for(int i = 0; i < n; i++) { scanf("%d%d", &s[i], &e[i]); rec[p++] = s[i]; rec[p++] = e[i]; } for(int i = 0; i < m; i++) { scanf("%d", &Q[i]); rec[p++] = Q[i]; } //离散化 sort(rec+1, rec+p); int R = 2; for(int i = 2; i < p; i++) if(rec[i] != rec[i-1]) rec[R++] = rec[i]; sort(rec+1, rec+R); build(1, 1, R-1); for(int i = 0; i < n; i++) { int x = Find(1, R-1, s[i]); int y = Find(1, R-1, e[i]); update(x, y, 1); } printf("Case #%d:\n", k++); for(int i = 0; i < m; i++) { int x = Find(1, R-1, Q[i]); printf("%d\n", query(1, x)); } } return 0; }