线段树+离散化

http://acm.hdu.edu.cn/showproblem.php?pid=4325

题意:

  有n种花每种开放的时间从a到b(a到b的闭区间),问t时刻有多少种花开着(n<=10^6,a<=b<10^9)

 1 #include <cstdio>

 2 #include <algorithm>

 3 #include <iostream>

 4 using namespace std;

 5 const int Ni = 1000010;

 6 struct node {

 7     int l,r,sum;

 8 }tree[Ni*3];

 9 struct node1{

10     int l,r;

11 }flo[Ni];

12 int x[Ni*2];

13 int n,m;

14 void build(int l,int r,int i)

15 {

16     tree[i].l=x[l];tree[i].r=x[r];

17     tree[i].sum=0;

18     if(l==r) return ;

19     int mid=(l+r)>>1;

20     build(l,mid,i<<1);

21     build(mid+1,r,i<<1|1);

22 }

23 void update(int l,int r,int i)

24 {

25     if(l<=tree[i].l&&tree[i].r<=r)

26         {tree[i].sum++;return;}

27 

28     if(r<=tree[i<<1].r) update(l,r,i<<1);

29     else if(l>=tree[i<<1|1].l) update(l,r,i<<1|1);

30     else

31     {

32         update(l,tree[i<<1].r,i<<1);

33         update(tree[i<<1|1].l,r,i<<1|1);

34     }

35 }

36 int qurey(int key,int i)

37 {

38     int ans=tree[i].sum;

39     if(tree[i].l==tree[i].r)//到叶子结点

40         return tree[i].sum;

41     if(key<=tree[i<<1].r)//在左子树

42         return ans+qurey(key,i<<1);

43     if(key>=tree[i<<1|1].l)//在右子树

44         return ans+qurey(key,i<<1|1);

45     int a=qurey(key,i<<1);//在中间

46     int b=qurey(key,i<<1|1);

47     ans+=min(a,b);

48     return ans;

49 }

50 int main()

51 {

52     int cs=1,i,t,q,num;

53     cin>>t;

54     for(cs=1;cs<=t;cs++)

55     {

56         cin>>n>>m;

57         for(num=i=0;i<n;i++)

58         {

59             scanf("%d%d",&flo[i].l,&flo[i].r);

60             x[num++]=flo[i].l;

61             x[num++]=flo[i].r;

62         }

63         sort(x,x+num);

64         num=(num-1)<<1;

65         for(i=num;i>=0;i-=2)//插点

66         {

67             x[i]=x[i>>1];

68             x[i-1]=(x[i>>1]+x[(i>>1)-1])>>1;

69         }

70         for(i=1,q=0;i<=num;i++)//缩点

71         {

72             if(x[q]!=x[i]) x[++q]=x[i];

73         }

74         build(0,num=q,1);//0到num的结点建树

75         for(i=0;i<n;i++)

76         {

77             update(flo[i].l,flo[i].r,1);

78         }

79         printf("Case #%d:\n",cs);

80         for(i=0;i<m;i++)

81         {

82             scanf("%d",&q);

83             if(q<x[0]||q>x[num]) printf("0\n");

84             else

85             printf("%d\n",qurey(q,1));

86         }

87     }

88     return 0;

89 }

90 /*

91 1

92 3 100

93 4 5

94 2 7

95 7 10

96 6

97 */

 

 

你可能感兴趣的:(线段树)