zoukankan      html  css  js  c++  java
  • hdoj 4251 The Famous ICPC Team Again

    The Famous ICPC Team Again

    Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 203    Accepted Submission(s): 91


    Problem Description
    When Mr. B, Mr. G and Mr. M were preparing for the 2012 ACM-ICPC World Final Contest, Mr. B had collected a large set of contest problems for their daily training. When they decided to take training, Mr. B would choose one of them from the problem set. All the problems in the problem set had been sorted by their time of publish. Each time Prof. S, their coach, would tell them to choose one problem published within a particular time interval. That is to say, if problems had been sorted in a line, each time they would choose one of them from a specified segment of the line.

    Moreover, when collecting the problems, Mr. B had also known an estimation of each problem’s difficultness. When he was asked to choose a problem, if he chose the easiest one, Mr. G would complain that “Hey, what a trivial problem!”; if he chose the hardest one, Mr. M would grumble that it took too much time to finish it. To address this dilemma, Mr. B decided to take the one with the medium difficulty. Therefore, he needed a way to know the median number in the given interval of the sequence.
     
    Input
    For each test case, the first line contains a single integer n (1 <= n <= 100,000) indicating the total number of problems. The second line contains n integers xi (0 <= xi <= 1,000,000,000), separated by single space, denoting the difficultness of each problem, already sorted by publish time. The next line contains a single integer m (1 <= m <= 100,000), specifying number of queries. Then m lines follow, each line contains a pair of integers, A and B (1 <= A <= B <= n), denoting that Mr. B needed to choose a problem between positions A and B (inclusively, positions are counted from 1). It is guaranteed that the number of items between A and B is odd.
     
    Output
    For each query, output a single line containing an integer that denotes the difficultness of the problem that Mr. B should choose.
     
    Sample Input
    5 5 3 2 4 1 3 1 3 2 4 3 5 5 10 6 4 8 2 3 1 3 2 4 3 5
     
    Sample Output
    Case 1: 3 3 2 Case 2: 6 6 4
     
    Source
     
     
    这题是直接划分树套模板 但是我没学过划分树 听他们说了我也不知道 百度搜到一篇关于POJ 询问第K个大的数 最典型的划分树的题目
    以后遇到也是贴模板吧  确实不想去学了 懒啊!!!
    这是运行最快的一个代码
     1 #include<iostream>
     2 #include<algorithm>
     3 #include<stdio.h>
     4 using namespace std;
     5 const int A=100010;
     6 int srt[A];//排序数组
     7 int val[18][A];//记录每次划分时的元素
     8 int toleft[18][A];//toleft[i][j]第i层的第j个之前包括第j个有多少个被分到左孩子。
     9 struct Node{
    10     int l,r;
    11 };
    12 inline int L(int x){ return (x<<1)+1;}
    13 inline int R(int x){ return (x<<1)+2;}
    14 Node node[A<<2];
    15 
    16 void build_tree(int s,int e,int row,int pos)
    17 {
    18     node[pos].l=s;
    19     node[pos].r=e;
    20     if(s==e) return;
    21 
    22     int mid=(s+e)>>1;
    23     int lsame=mid+1-s;//lsame表示和srt[mid]相等且分到左边的元素的个数
    24     for(int i=s;i<=e;i++)
    25     {
    26         if(val[row][i]<srt[mid])
    27             lsame--;
    28     }
    29     int l=s;int r=mid+1;
    30     for(int i=s;i<=e;i++) //计算被划分到左子树的元素个数。
    31     {
    32         toleft[row][i]=(i==s?0:toleft[row][i-1]);
    33         if(val[row][i]<srt[mid])
    34         {
    35             val[row+1][l++]=val[row][i];
    36             toleft[row][i]++;
    37         }
    38         else if(val[row][i]>srt[mid])
    39         {
    40             val[row+1][r++]=val[row][i];
    41         }
    42         else if(lsame)
    43         {
    44             val[row+1][l++]=val[row][i];
    45             toleft[row][i]++;
    46             lsame--;
    47 
    48         }
    49         else
    50         {
    51             val[row+1][r++]=val[row][i];
    52         }
    53     }
    54     build_tree(s,mid,row+1,L(pos));
    55     build_tree(mid+1,e,row+1,R(pos));
    56 
    57 }
    58 int query(int s,int e,int k,int row,int pos)
    59 {
    60     if(s==e) return val[row][s];
    61     int LL= ((s==node[pos].l)?0:toleft[row][s-1]);//LL表示[ node[id].l , l-1 ]有多少个分到左边
    62     int LI=toleft[row][e]-LL;//LI表示[ l , r ]有多少个分到左边
    63     if(k<=LI)
    64         return query(node[pos].l+LL,node[pos].l+LL+LI-1,k,row+1,L(pos));
    65     int mid=(node[pos].l+node[pos].r)>>1;
    66     int RL= s-node[pos].l-LL;//RL表示[ node[id].l , l-1 ]有多少个分到右边
    67     int RI= e-s+1-LI; //RI表示[ l , r ]有多少个分到右边
    68     return query(mid+1+RL,mid+1+RL+RI-1,k-LI,row+1,R(pos));
    69 }
    70 int main()
    71 {
    72     //freopen("1.txt","r",stdin);
    73     //freopen("2.txt","w",stdout);
    74     int m,n;
    75     int sum=1;
    76     while(~scanf("%d",&n))
    77     {
    78         printf("Case %d:\n",sum++);
    79         for(int i=0;i<n;i++)
    80         {
    81             scanf("%d",srt+i);
    82             val[0][i]=srt[i];
    83         }
    84         sort(srt,srt+n);
    85         build_tree(0,n-1,0,0);
    86         scanf("%d",&m);
    87         int s,e,k;
    88         for(int i=0;i<m;i++)
    89         {
    90             scanf("%d%d",&s,&e);
    91             printf("%d\n",query(s-1,e-1,(e-s)/2+1,0,0));
    92         }
    93 
    94     }
    95 }
    这是标程 但是运行了9S
     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 #define ran 100010
     5 using namespace std;
     6 int n,m,a[ran],b[ran];
     7 int s[ran*18];
     8 void build(int i,int st,int en){
     9     memcpy(s+i+st,a+st,sizeof(int)*(en-st));
    10     sort(s+i+st,s+i+en);
    11     if(st+1==en)return;
    12     int mi=(st+en)/2;
    13     build(i+n,st,mi);
    14     build(i+n,mi,en);
    15 }
    16 int calc(int i,int st,int en,int le,int ri,int x){
    17     if(st==le && en==ri)
    18         return lower_bound(s+i+st,s+i+en,x)-(s+i+st);
    19     int mi=(st+en)/2;
    20     if(ri<=mi)
    21         return calc(i+n,st,mi,le,ri,x);
    22     if(le>=mi)
    23         return calc(i+n,mi,en,le,ri,x);
    24     return calc(i+n,st,mi,le,mi,x)+calc(i+n,mi,en,mi,ri,x);
    25 }
    26 int main(){
    27     int w,x,y;
    28     for(int t=1; ~scanf("%d",&n); t++){
    29         for(int i=0; i<n; i++){
    30             scanf("%d",&a[i]);
    31             b[i]=a[i];
    32         }
    33         sort(b,b+n);
    34         m=unique(b,b+n)-b;
    35         for(int i=0; i<n; i++)
    36             a[i]=lower_bound(b,b+m,a[i])-b;
    37         build(0,0,n);
    38         printf("Case %d:\n",t);
    39         for(scanf("%d",&w); w--;){
    40             scanf("%d%d",&x,&y);--x;
    41             int lo=0,hi=m-1;
    42             while(lo!=hi){
    43                 int mi=(lo+hi+1)/2;
    44                 if(calc(0,0,n,x,y,mi)<=(y-x)/2)
    45                     lo=mi;
    46                 else
    47                     hi=mi-1;
    48             }
    49             printf("%d\n",b[lo]);
    50         }
    51     }
    52     return 0;
    53 }
    运行2S 短小精悍的代码
     1 #include<stdio.h>
     2 #include<algorithm>
     3 #include<map>
     4 #include<vector>
     5 
     6 using namespace std;
     7 
     8 int n, m;
     9 int a[100005], x[100005];
    10 vector<int> bit[100005];
    11 
    12 void add(int id, int v) {
    13     while(v <= n) {
    14         bit[v].push_back(id);
    15         v += (v & -v);
    16     }
    17 }
    18 
    19 int query(int L, int R, int v) {
    20     int u = 0, now = 0;
    21     for(int i=20; i>=0; i--) {
    22         if(u + (1<<i) <= n) {
    23             u += (1<<i);
    24             int g = upper_bound(bit[u].begin(), bit[u].end(), R) - lower_bound(bit[u].begin(), bit[u].end(), L);
    25             if(now + g >= v) u -= (1<<i);
    26             else now += g;
    27         }
    28     }
    29     return x[u+1];
    30 }
    31 
    32 int main() {
    33     int test = 0;
    34     while(scanf("%d", &n) != EOF) {
    35         for(int i=1; i<=n; i++) {
    36             scanf("%d", &a[i]);
    37             x[i] = a[i];
    38             bit[i].clear();
    39         }
    40         sort(x+1, x+n+1);
    41         for(int i=1; i<=n; i++) {
    42             a[i] = lower_bound(x+1, x+n+1, a[i]) - x;
    43             add(i, a[i]);
    44         }
    45         for(int i=1; i<=n; i++) {
    46             sort(bit[i].begin(), bit[i].end());
    47         }
    48         printf("Case %d:\n", ++test);
    49         scanf("%d", &m);
    50         for(int i=1, A, B; i<=m; i++) {
    51             scanf("%d%d", &A, &B);
    52             printf("%d\n", query(A, B, (B-A)/2+1));
    53         }
    54     }
    55     return 0;
    56 }


     

  • 相关阅读:
    Pentaho BIServer Community Edtion 6.1 使用教程 第三篇 发布和调度Kettle(Data Integration) 脚本 Job & Trans
    Pentaho BIServer Community Edtion 6.1 使用教程 第二篇 迁移元数据 [HSQLDB TO MySQL]
    Pentaho BIServer Community Edtion 6.1 使用教程 第一篇 软件安装
    C调用约定__cdecl、__stdcall、__fastcall、__pascal分析
    django环境搭建和学习
    Nagios学习笔记
    MFC下的DLL编程学习
    从零开始学区块链(4)
    从零开始学区块链(3)
    从零开始学习区块链(2)
  • 原文地址:https://www.cnblogs.com/wujianwei/p/2598621.html
Copyright © 2011-2022 走看看