• 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;
    }
  • 相关阅读:
    linux-kernel邮件列表订阅出错,提示命令不能识别---解决方案
    MD5(单向散列算法)原理分析
    win32汇编跳转指令用法
    (转载)c/c++优先级列表
    linux man手册各个章节的意义
    如何解决dpkg: error processing install-info
    python魔法函数(常见)
    redis 哈希封装
    数据库去重
    抖音破解字体加密
  • 原文地址:https://www.cnblogs.com/lhclqslove/p/8688716.html
Copyright © 2020-2023  润新知