zoukankan      html  css  js  c++  java
  • 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:
    ",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
    ",ans);
    93         }
    94     }
    95     return 0;
    96 }
  • 相关阅读:
    Jenkins发布.Net Core项目到IIS
    2019 SDN上机第2次作业
    2019 SDN上机第1次作业
    第二次结对编程作业
    第3组 团队展示
    第一次结对编程作业
    第一次个人编程作业
    第一次博客作业
    android json解析及简单例子
    详述Google针对Android平板App发布的十大开发准则
  • 原文地址:https://www.cnblogs.com/fraud/p/4397168.html
Copyright © 2011-2022 走看看