zoukankan      html  css  js  c++  java
  • 山东第四届省赛: Boring Counting 线段树

    http://acm.sdibt.edu.cn/JudgeOnline/problem.php?id=3237

    Problem H:Boring Counting

    Time Limit: 3 Sec  Memory Limit: 128 MB
    Submit: 6  Solved: 2
    [Submit][Status][Discuss]

    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

    山东省第四届ACM程序设计大赛2013.6.9

    比赛的时候,没有头绪,今天别人说起划分树,想了一下,还真是可以做的。

    但是要一点变形,这样的变形,让我已经看不清 划分树的影子了。

    划分树----求区间第K 小/大 值

    这道题是求区间求区间[l,r]中 满足  A<=xi<=B; xi属于[l,r]。求xi的个数。

    如何转化的呢? 

                         枚举区间第k小数==A。此时能求出一个值 hxl

                         枚举区间第K小数==B,此时得到一个值   tom

                         显然满足tom>=hxl。

                         那在这范围的数,是不是就满足了  A<=xi<=B  !~~

    这么一说,其实好简单。为什么没有想到呢?  划分树做的时候是求 第 k 小的是什么什么数字,现在换了回来而已,

    求的是某个数字是区间里面第几小。

    其实有个问题就又来了,A,B在区间[l,r]未必存在,这该怎么办?????

    其实上面的说法,不严谨,(求的是某个数字是区间里面第几小。)应该说是求A的下届,B的上届值。

    二分枚举,平均的时间会更小。在求下届和上届的过程中也要注意一些细节的问题、

      1 #include<cstdio> 
      2 #include<iostream> 
      3 #include<cstdlib> 
      4 #include<algorithm> 
      5 #include<cstring> 
      6 #define N 100010 
      7 using namespace std; 
      8   
      9 int toleft[30][N]; 
     10 int Tree[30][N]; 
     11 int Sort[N]; 
     12   
     13   
     14   
     15 void build(int l,int r,int dep) 
     16 { 
     17     int mid=(l+r)/2,sum=mid-l+1,lpos,rpos,i; 
     18     if(l==r) return ; 
     19     for(i=l;i<=r;i++) 
     20         if(Tree[dep][i]<Sort[mid]) sum--; 
     21     lpos=l; 
     22     rpos=mid+1; 
     23     for(i=l;i<=r;i++) 
     24     { 
     25         if(Tree[dep][i]<Sort[mid]) 
     26         { 
     27             Tree[dep+1][lpos++]=Tree[dep][i]; 
     28         } 
     29         else if(Tree[dep][i]==Sort[mid] && sum>0) 
     30         { 
     31             Tree[dep+1][lpos++]=Tree[dep][i]; 
     32             sum--; 
     33         } 
     34         else
     35         { 
     36             Tree[dep+1][rpos++]=Tree[dep][i]; 
     37         } 
     38         toleft[dep][i]=toleft[dep][l-1]+lpos-l; 
     39     } 
     40     build(l,mid,dep+1); 
     41     build(mid+1,r,dep+1); 
     42 } 
     43   
     44 int query(int L,int R,int l,int r,int dep,int k) 
     45 { 
     46     int mid=(L+R)/2,newl,newr,cur; 
     47     if(l==r) return Tree[dep][l]; 
     48     cur=toleft[dep][r]-toleft[dep][l-1]; 
     49     if(cur>=k) 
     50     { 
     51         newl=L+toleft[dep][l-1]-toleft[dep][L-1]; 
     52         newr=newl+cur-1; 
     53         return query(L,mid,newl,newr,dep+1,k); 
     54     } 
     55     else
     56     { 
     57         newr=r+(toleft[dep][R]-toleft[dep][r]); 
     58         newl=newr-(r-l-cur); 
     59         return query(mid+1,R,newl,newr,dep+1,k-cur); 
     60     } 
     61 } 
     62 int EF1(int l,int r,int num,int n) //枚举下届
     63 { 
     64     int low=1,right=r-l+1,mid,tmp; 
     65     mid=(low+right)/2; 
     66     while(low<right) 
     67     { 
     68         tmp=query(1,n,l,r,0,mid); 
     69         if(tmp>=num) 
     70         right=mid-1; 
     71         else low=mid; //!!!!
     72         mid=(low+right+1)/2; //!!! 加了一个1。
     73     } 
     74     return low; 
     75   
     76 } 
     77   
     78 int EF2(int l,int r,int num,int n) 
     79 { 
     80     int low=1,right=r-l+1,mid,tmp; 
     81     mid=(low+right)/2; 
     82     while(low<right) 
     83     { 
     84         tmp=query(1,n,l,r,0,mid); 
     85         if(tmp>num) 
     86         right=mid; //!!!
     87         else low=mid+1; 
     88         mid=(low+right)/2; //木有加1
     89     } 
     90     return low; 
     91 } 
     92   
     93 int main() 
     94 { 
     95     int T,n,m,i,l,r,k,a,b,hxl,tom,qq; 
     96     scanf("%d",&T); 
     97     { 
     98         for(qq=1;qq<=T;qq++) 
     99         { 
    100             scanf("%d%d",&n,&m); 
    101             memset(Tree,0,sizeof(Tree)); 
    102             for(i=1;i<=n;i++) 
    103             { 
    104                 scanf("%d",&Tree[0][i]); 
    105                 Sort[i]=Tree[0][i]; 
    106             } 
    107             sort(Sort+1,Sort+1+n); 
    108             build(1,n,0); 
    109             printf("Case #%d:
    ",qq); 
    110             while(m--) 
    111             { 
    112                 scanf("%d%d%d%d",&l,&r,&a,&b); 
    113                 hxl=query(1,n,l,r,0,1); 
    114                 if(a<=hxl) hxl=1; //对临界条件的判断。如果A就是最小的,木有下届
    115                 else
    116                 { 
    117                     hxl=EF1(l,r,a,n); 
    118                     hxl++; 
    119                 } 
    120                 tom=query(1,n,l,r,0,r-l+1); 
    121                 if(b>=tom) tom=r-l+1; //如果B是该区间[l,r]最大的,显然木有上届
    122                 else
    123                 { 
    124                     tom=EF2(l,r,b,n); 
    125                     tom--; 
    126                 } 
    127                 hxl=tom-hxl+1; 
    128                 printf("%d
    ",hxl); 
    129             } 
    130         } 
    131     } 
    132     return 0; 
    133 } 
  • 相关阅读:
    每日立会2015-11-30
    Some Modern Softwares' drawbacks: User experience 12/29/2015
    Sprint 5 summary: UI 界面更新,Azure端部署和用户反馈分析 12/28/2015
    Daily Scrum 12/25/2015
    Daily Scrum 12/24/2015
    Daily Scrum 12/23/2015
    Daily Scrum 12/21/2015
    Daily Scrum 12/18/2015
    Daily Scrum 12/17/2015
    Performance standard (ALPHA release) 12/17/2015
  • 原文地址:https://www.cnblogs.com/tom987690183/p/3257594.html
Copyright © 2011-2022 走看看