HDU 4417 Super Mario主席树

题目链接:Super Mario

题解:几乎跟第K大查不多的主席树,先把按数组建好主席树,然后询问的时候注意L,R,它范围是从0到n-1,然后二分找到H是原数组中的第几大=K,查询1~k的sum[]

的和就可以

#include<bits/stdc++.h>
#include<set>
#include<cstdio>
#include<iomanip>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#define pb push_back
#define ll long long
#define PI 3.14159265
//#define ls l,m,rt<<1
//#define rs m+1,r,rt<<1|1
#define eps 1e-7
typedef unsigned long long ull;
const int mod=1e9+9;
const ll inf=0x3f3f3f3f3f3f3f;
const int maxn=1e5+5;
using namespace std;
int a[maxn],b[maxn],sum[maxn*30],rt[maxn],n,m,sz,t;
int ls[maxn*30],rs[maxn*30],tot;
void build(int &o,int l,int r)
{
    o=++tot;
    sum[o]=0;
    if(l==r)return;
    int m=(l+r)>>1;
    build(ls[o],l,m);
    build(rs[o],m+1,r);
}
void update(int &o,int pre,int l,int r,int x)
{
    o=++tot;
    sum[o]=sum[pre]+1;
    ls[o]=ls[pre];
    rs[o]=rs[pre];
    if(l==r)return;
    int m=(l+r)>>1;
    if(x<=m)update(ls[o],ls[pre],l,m,x);
    else update(rs[o],rs[pre],m+1,r,x);
}
int query(int pl,int pr,int l,int r,int x)
{
    if(r==l)
    {
        return sum[pr]-sum[pl];
    }
    int m=(l+r)>>1;
    if(x<=m)return query(ls[pl],ls[pr],l,m,x);
    else return sum[ls[pr]]-sum[ls[pl]]+query(rs[pl],rs[pr],m+1,r,x);
}
int main()
{
    scanf("%d",&t);
    int num=1;
    while(t--)
    {
        scanf("%d %d",&n,&m);
        tot=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);b[i]=a[i];
        }
        sort(b+1,b+n+1);
        int sz=unique(b+1,b+1+n)-b-1;
        for(int i=1;i<=n;i++)
        {
            a[i]=lower_bound(b+1,b+1+sz,a[i])-b;
        }
        build(rt[0],1,sz);
        for(int i=1;i<=n;i++)update(rt[i],rt[i-1],1,sz,a[i]);
        printf("Case %d:
",num++);
        while(m--)
        {
            int l,r,h;
            scanf("%d %d %d",&l,&r,&h);
            if(h<b[1])
            {
                printf("0
");continue;
            }
            else if(h>=b[sz])
            {   printf("%d
",r-l+1);continue;}

            int p=lower_bound(b+1,b+sz+1,h)-b;
            if(b[p]>h)p--;
           // printf("####%d
",p);
            printf("%d
",query(rt[l],rt[r+1],1,sz,p));
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/lhclqslove/p/8688716.html