题目大意:一个农园有n个花朵,给出每朵花的开花时间(用区间表示),求在特定时间点的开花的花朵数量。

思路:离散化,线段树。在建树时有些点表示单个时间点,有些要表示时间区间。然后单点查询即可。

View Code
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 using namespace std;
  5 #define lson l,m,rt<<1
  6 #define rson m+1,r,rt<<1|1
  7 #define maxn 100010
  8 struct node
  9 {
 10     int cnt;
 11 }setree[maxn<<3];
 12 int xx[maxn<<2];
 13 struct 
 14 {
 15     int l,r;
 16 }info[maxn<<3];
 17 int left[maxn];
 18 int right[maxn];
 19 void build(int l,int r,int rt)
 20 {
 21     setree[rt].cnt=0;
 22     if(l==r)
 23     return;
 24     int m=(l+r)>>1;
 25     build(lson);
 26     build(rson);
 27 }
 28 void pushdown(int rt)
 29 {
 30     if(setree[rt].cnt){
 31         setree[rt<<1].cnt+=setree[rt].cnt;
 32         setree[rt<<1|1].cnt+=setree[rt].cnt;
 33         setree[rt].cnt=0;
 34     }
 35 }
 36 void update(int l,int r,int rt,int L,int R)
 37 {
 38     if(L<=l&&r<=R){
 39         setree[rt].cnt++;
 40         return;
 41     }
 42     pushdown(rt);
 43     int m=(l+r)>>1;
 44     if(L<=m)
 45     update(lson,L,R);
 46     if(R>m)
 47     update(rson,L,R);
 48 }
 49 int query(int l,int r,int rt,int num)
 50 {
 51     if(l==r)
 52     return setree[rt].cnt;
 53     pushdown(rt);
 54     int m=(l+r)>>1;
 55     if(num<=m)
 56     return query(lson,num);
 57     else 
 58     return query(rson,num);
 59 }
 60 int binsearch(int l,int r,int key)
 61 {
 62     if(l>r)
 63     return -1;
 64     int m=(l+r)>>1;
 65     if(info[m].l<=key&&key<=info[m].r)
 66     return m;
 67     if(info[m].l>key)
 68     return binsearch(l,m-1,key);
 69     else if(info[m].r<key)
 70     return binsearch(m+1,r,key);
 71 }
 72 int main()
 73 {
 74     int n,k,t,m,i,cas=1;
 75     scanf("%d",&t);
 76     while(t--){
 77         scanf("%d%d",&n,&m);
 78         k=1;
 79         for(i=1;i<=n;i++){
 80             scanf("%d%d",left+i,right+i);
 81             xx[k++]=left[i];
 82             xx[k++]=right[i];
 83         }
 84         sort(xx+1,xx+k);
 85         int nk=2;
 86         for(i=2;i<k;i++)
 87         if(xx[i]!=xx[i-1])
 88         xx[nk++]=xx[i];
 89         k=nk;
 90         int k1=2;
 91         info[1].l=info[1].r=xx[1];
 92         for(i=2;i<k;i++){
 93             if(xx[i]-xx[i-1]>1){
 94                 info[k1].l=xx[i-1]+1;
 95                 info[k1].r=xx[i]-1;
 96                 k1++;
 97             }
 98             info[k1].l=xx[i];
 99             info[k1].r=xx[i];
100             k1++;
101         }
102         k=k1;
103         build(1,k-1,1);
104         for(i=1;i<=n;i++){
105             int l=binsearch(1,k-1,left[i]);
106             int r=binsearch(1,k-1,right[i]);
107             update(1,k-1,1,l,r);
108         }
109         printf("Case #%d:\n",cas++);
110         while(m--){
111             int a;
112             scanf("%d",&a);
113             a=binsearch(1,k-1,a);
114             if(a==-1)
115             printf("0\n");
116             else
117             printf("%d\n",query(1,k-1,1,a));
118         }
119     }
120     return 0;
121 }