• HDU 4417 Super Mario(划分树)


     

    题目大意

     

    给你 n(1<=n<=10^5) 个数,m(1<=m<=10^5) 个询问,每个询问的格式如下

    L R H:从第 L 个数到第 R 个数中,小于等于 H 的数有多少个

     

    做法分析

     

    建立划分树

    每次 query 的时候,二分答案即可,即二分这个区间中有多少个小于等于 H 的数

     

    参考代码

    HDU 4417
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 
     6 using namespace std;
     7 
     8 const int N=100006;
     9 
    10 struct devided_tree
    11 {
    12     int val[20][N], f[20][N], sorted[N];
    13 
    14     void build(int L, int R, int deep)
    15     {
    16         if(L==R) return;
    17         int mid=(L+R)>>1;
    18         int midVal=sorted[mid], tot=mid-L+1;
    19         for(int i=L; i<=R; i++) if(val[deep][i]<midVal) tot--;
    20         int sL=L, sR=mid+1;
    21         for(int i=L; i<=R; i++)
    22         {
    23             f[deep][i]=(i==L)?0:f[deep][i-1];
    24             if(val[deep][i]<midVal || (val[deep][i]==midVal && tot))
    25             {
    26                 val[deep+1][sL++]=val[deep][i];
    27                 f[deep][i]++;
    28                 if(val[deep][i]==midVal) tot--;
    29             }
    30             else val[deep+1][sR++]=val[deep][i];
    31         }
    32         build(L, mid, deep+1), build(mid+1, R, deep+1);
    33     }
    34 
    35     int query(int L, int R, int st, int en, int k, int deep)
    36     {
    37         if(st==en) return val[deep][st];
    38         int mid=(L+R)>>1;
    39         int L1=(L==st)?0:f[deep][st-1];
    40         int L2=f[deep][en]-L1;
    41         if(k<=L2) return query(L, mid, L+L1, L+L1+L2-1, k, deep+1);
    42         int R1=(st-1-L+1)-L1;
    43         int R2=(en-st+1)-L2;
    44         return query(mid+1, R, mid+1+R1, mid+1+R1+R2-1, k-L2, deep+1);
    45     }
    46 } tree;
    47 
    48 int main()
    49 {
    50     int t, n, m;
    51     scanf("%d", &t);
    52     for(int ca=1; ca<=t; ca++)
    53     {
    54         scanf("%d%d", &n, &m);
    55         for(int i=0; i<n; i++)
    56         {
    57             scanf("%d", &tree.val[0][i]);
    58             tree.sorted[i]=tree.val[0][i];
    59         }
    60         sort(tree.sorted, tree.sorted+n);
    61         tree.build(0, n-1, 0);
    62         printf("Case %d:\n", ca);
    63         for(int i=0, a, b, c; i<m; i++)
    64         {
    65             scanf("%d%d%d", &a, &b, &c);
    66             int L=1, R=b-a+1;
    67             while(L<R)
    68             {
    69                 int mid=(L+R)>>1;
    70                 int keyVal=tree.query(0, n-1, a, b, mid, 0);
    71                 if(keyVal<=c) L=mid+1;
    72                 else R=mid;
    73             }
    74             if(tree.query(0, n-1, a, b, L, 0)>c) L--;
    75             printf("%d\n", L);
    76         }
    77     }
    78     return 0;
    79 }

    AC通道

    HDU 4417 Super Mario

  • 相关阅读:
    zen_cart 支付提前生成订单
    SSL加密过程
    建立自己的代码库
    自动代码工具
    mssqlserver 学习资源
    自己动手写操作系统(1)
    Windows Phone 7 优秀开源项目收集
    正则表达式工具
    .net framework source code
    vs2012 打包应用程序(创建部署/安装包)
  • 原文地址:https://www.cnblogs.com/zhj5chengfeng/p/2964072.html
Copyright © 2020-2023  润新知