zoukankan      html  css  js  c++  java
  • codves 2021中庸之道

    2021 中庸之道

    http://codevs.cn/problem/2021/

    题目描述 Description

    给定一个长度为N的序列,有Q次询问,每次询问区间[L,R]的中位数。

    数据保证序列中任意两个数不相同,且询问的所有区间长度为奇数。

    输入描述 Input Description

    第一行为N,Q。

    第二行N个数表示序列。

    接下来Q行,每行为L,R,表示一次询问。

    输出描述 Output Description

    输出Q行,对应每次询问的中位数。

     
    样例输入 Sample Input

    5 3

    1 4 8 16 2

    1 5

    3 5

    3 3

    样例输出 Sample Output

    4

    8

    8

    数据范围及提示 Data Size & Hint

    40%的数据,N,Q≤100;

    70%的数据,N≤100;

    100%的数据,N≤1000,Q≤100000,序列中的元素为1到10^9之间的整数。

    套上主席树求第K大模板

    区间[l,r]中位数转化:k=(r-l)/2+1

    例:[5,9]中位数是第7个,k=(9-5)/2+1=3,是第3大

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #define N 100001
    using namespace std;
    int n,m,l_child[N*18],r_child[N*18],root[N],sum[N*18],tot,id;
    int a[N],has[N];
    int x,y,k,ans,T;
    void build(int pre,int &now,int key,int l,int r)
    {
        sum[now=++id]=sum[pre]+1;
        if(l==r) return;
        int mid=(l+r)/2;
        if(key<=mid)
        {
            r_child[now]=r_child[pre];
            build(l_child[pre],l_child[now],key,l,mid);
        }
        else
        {
            l_child[now]=l_child[pre];
            build(r_child[pre],r_child[now],key,mid+1,r);
        }
    }
    void discrete()
    {
        sort(a+1,a+n+1);
        tot=unique(a+1,a+n+1)-(a+1);
        for(int i=1;i<=n;i++) has[i]=lower_bound(a+1,a+tot+1,has[i])-a;
    }
    int search(int s,int t,int k,int l,int r)
    {
        if(l==r) return l;
        int tmp=sum[l_child[t]]-sum[l_child[s]];
        int mid=(l+r)/2;
        if(tmp>=k) return search(l_child[s],l_child[t],k,l,mid);
        else return search(r_child[s],r_child[t],k-tmp,mid+1,r);
    }
    int main()
    {
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++) scanf("%d",&a[i]),has[i]=a[i];
            discrete();
            for(int i=1;i<=n;i++) build(root[i-1],root[i],has[i],1,tot);
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d",&x,&y);
                k=(y-x)/2+1;//转化
                ans=search(root[x-1],root[y],k,1,tot);
                printf("%d
    ",a[ans]);
            }    
    }
  • 相关阅读:
    ScheduledThreadPoolExecutor源码解读
    Spring事务源码阅读笔记
    Spring AOP的实现研究
    cglib之Enhancer
    Spring IOC容器创建bean过程浅析
    CompletionService简讲
    Spring Boot:关于“No converter found for return value of type: class xxx”的解决方法
    java关于Date转换成字符串格式以及Date的增加
    jsp中文乱码六种情况---解决方案
    MYSQL给表添加字段
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/6291149.html
Copyright © 2011-2022 走看看