13年山东省赛 Boring Counting(离线树状数组or主席树+二分or划分树+二分)

转载请注明出处: http://www.cnblogs.com/fraud/           ——by fraud

 

2224: Boring Counting

Time Limit: 3 Sec  Memory Limit: 128 MB

Description

In this problem you are given a number sequence P consisting of N integer and Pi is the ith element in the sequence. Now you task is to answer a list of queries, for each query, please tell us among [L, R], how many Pi is not less than A and not greater than B( L<= i <= R). In other words, your task is to count the number of Pi (L <= i <= R,  A <= Pi <= B).

 

Input

In the first line there is an integer T (1 < T <= 50), indicates the number of test cases. 
       For each case, the first line contains two numbers N and M (1 <= N, M <= 50000), the size of sequence P, the number of queries. The second line contains N numbers Pi(1 <= Pi <= 10^9), the number sequence P. Then there are M lines, each line contains four number L, R, A, B(1 <= L, R <= n, 1 <= A, B <= 10^9)

 

Output

For each case, at first output a line ‘Case #c:’, c is the case number start from 1. Then for each query output a line contains the answer.

 

Sample Input

1

13 5

6 9 5 2 3 6 8 7 3 2 5 1 4

1 13 1 10

1 13 3 6

3 6 3 6

2 8 2 8

1 9 1 9

Sample Output

Case #1:

13

7

3

6

9

HINT

 

Source

题意:求静态的区间[l,r]介于[A,B]的数的个数

这题其实是一道离线树状数组的水题,估计是因为我并不是很具备离线的思维吧,一般的离线都想不到。

好在主席树也能够完成这个操作,并且也只花了20分钟不到就1A了。

二分k的值,然后判断利用第k大来判断出A,B分别是第几大。然后随便搞。

 1 #include <cstdio>

 2 #include <cstring>

 3 #include <iostream>

 4 #include <algorithm>

 5 #include <cmath>

 6 #include <cstdlib>

 7 #include <vector>

 8 using namespace std;

 9 #define w(i) T[i].w

10 #define ls(i) T[i].ls

11 #define rs(i) T[i].rs

12 #define MAXN 100010

13 int p[MAXN],a[MAXN],b[MAXN],root[MAXN];

14 struct node{

15     int ls,rs,w;

16     node(){ls=rs=w=0;}

17 }T[MAXN*20];

18 int tot=0;

19 void Insert(int &i,int l,int r,int x){

20     T[++tot]=T[i];

21     i=tot;

22     w(i)++;

23     if(l==r)return;

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

25     if(x<=mid)Insert(ls(i),l,mid,x);

26     else Insert(rs(i),mid+1,r,x);

27 }

28 int query(int lx,int rx,int l,int r,int k){

29     if(l==r)return l;

30     int ret=w(ls(rx))-w(ls(lx));

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

32     if(ret>=k)return query(ls(lx),ls(rx),l,mid,k);

33     else return query(rs(lx),rs(rx),mid+1,r,k-ret);

34 }

35 bool cmp(int i,int j){

36     return a[i]<a[j];

37 }

38 int main()

39 {

40     ios::sync_with_stdio(false);

41     tot=0;

42     int n,m;

43     int t;

44     int cas=1;

45     scanf("%d",&t);

46     while(t--){

47         scanf("%d%d",&n,&m);

48         for(int i=1;i<=n;i++){

49             scanf("%d",a+i);

50             p[i]=i;

51         }

52         tot=0;

53         root[0]=0;

54         sort(p+1,p+n+1,cmp);

55         for(int i=1;i<=n;i++)b[p[i]]=i;

56         for(int i=1;i<=n;i++){

57             root[i]=root[i-1];

58             Insert(root[i],1,n,b[i]);

59         }

60         printf("Case #%d:\n",cas++);

61         while(m--){

62             int l,r,x,y;

63             scanf("%d%d%d%d",&l,&r,&x,&y);

64             int lx=1,rx=r-l+1;

65             int fx=-1;

66             int ans=0;

67             int flag =0;

68             int tmpx;

69             while(lx<=rx){

70                 int mid = (lx+rx)>>1;

71                 tmpx=a[p[query(root[l-1],root[r],1,n,mid)]];

72                 if(tmpx<=y){

73                     fx=mid;

74                     lx=mid+1;

75                 }else rx=mid-1;

76             }

77             if(fx==-1)flag=1;

78             else ans+=fx;

79             lx=1,rx=r-l+1;

80             fx=-1;

81             while(lx<=rx){

82                 int mid = (lx+rx)>>1;

83                 tmpx=a[p[query(root[l-1],root[r],1,n,mid)]];

84                 if(tmpx>=x){

85                     fx=mid;

86                     rx=mid-1;

87                 }else lx=mid+1;

88             }

89             if(fx==-1)flag=1;

90             else ans=ans-fx+1;

91             if(flag)ans=0;

92             printf("%d\n",ans);

93         }

94     }

95     return 0;

96 }

 

你可能感兴趣的:(count)