• HDU4417 Super Mario


    划分树模板题

     1 #include<cstdio>
     2 #include<string>
     3 #include<vector>
     4 #include<algorithm>
     5 #define N 100009
     6 using namespace std;
     7 int n;
     8 int arr[N];//原数据
     9 int od[N];//排序后
    10 int lfnum[20][N];//元素所在区间的当前位置进入左孩子的元素的个数
    11 int val[20][N];//记录第k层当前位置的元素的值
    12 bool cmp(const int &x,const int &y)
    13 {
    14     return arr[x]<arr[y];
    15 }
    16 void build(int l,int r,int d)
    17 {
    18     if(l==r) return;
    19     int mid=(l+r)>>1,p=0;
    20     for(int i=l; i<=r; i++)
    21     {
    22         if(val[d][i]<=mid)
    23         {
    24             val[d+1][l+p]=val[d][i];
    25             lfnum[d][i]=++p;
    26         }
    27         else
    28         {
    29             lfnum[d][i]=p;
    30             val[d+1][mid+i+1-l-p]=val[d][i];
    31         }
    32     }
    33     build(l,mid,d+1);
    34     build(mid+1,r,d+1);
    35 }
    36 //求区间[s,e]第k大的元素
    37 int query(int s,int e,int k,int l=1,int r=n,int d=0)
    38 {
    39     if(l==r) return l;
    40     int mid=(l+r)>>1,ss,ee;
    41     ss=(s==l?0:lfnum[d][s-1]);
    42     ee=lfnum[d][e];
    43     if(ee-ss>=k) return query(l+ss,l+ee-1,k,l,mid,d+1);
    44     return query(mid+1+(s-l-ss),mid+1+(e-l-ee),k-(ee-ss),mid+1,r,d+1);
    45 }
    46 int main()
    47 {
    48     int cas=0,m,l,r,T,ql,qr;
    49     scanf("%d",&T);
    50     while(T--)
    51     {
    52         printf("Case %d:\n",++cas);
    53         scanf("%d%d",&n,&m);
    54         for(int i=1; i<=n; i++) scanf("%d",arr+i),od[i]=i;
    55         sort(od+1,od+n+1,cmp);
    56         for(int i=1; i<=n; i++) val[0][od[i]]=i;
    57         build(1,n,0);
    58         while(m--)
    59         {
    60             int num,v;
    61             scanf("%d%d%d",&ql,&qr,&v);
    62             ql++;qr++;
    63             l=1,r=qr-ql+1;
    64             while(l<=r)
    65             {
    66                 int mid=(l+r)>>1;
    67                 num=query(ql,qr,mid);
    68                 if(arr[od[num]]>v) r=mid-1;
    69                 else l=mid+1;
    70             }
    71             printf("%d\n",r);
    72         }
    73     }
    74 }
  • 相关阅读:
    【BZOJ】【3004】吊灯
    【BZOJ】【3653】谈笑风生
    【BZOJ】【2500】幸福的道路
    【BZOJ】【3612】【HEOI 2014】平衡
    【BZOJ】【1485】【HNOI2009】有趣的数列
    【BZOJ】【1293】【SCOI2009】生日礼物
    【BZOJ】【1055】【HAOI2008】玩具取名
    【BZOJ】【1053】【HAOI2007】反素数ant
    【BZOJ】【1052】【HAOI2007】覆盖问题
    【BZOJ】【1050】【HAOI2006】旅行comf
  • 原文地址:https://www.cnblogs.com/qijinbiao/p/2699757.html
Copyright © 2020-2023  润新知