• 中庸之道(codevs 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大 
    */
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #define N 100010
    using namespace std;
    int a[N],co[N],root[N],n,m,cnt;
    struct node
    {
        int lc,rc,sum;
    };node t[N*40];
    int read()
    {
        char c=getchar();int num=0,flag=1;
        while(c<'0'||c>'9'){if(c=='-')flag=-1;c=getchar();}
        while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();}
        return num*flag;
    }
    int build(int v,int x,int y)
    {
        int k=++cnt;t[k].sum=v;
        t[k].lc=x;t[k].rc=y;
        return k;
    }
    void insert(int &root,int pre,int l,int r,int pos)
    {
        root=build(t[pre].sum+1,t[pre].lc,t[pre].rc);
        if(l==r)return;
        int mid=(l+r)/2;
        if(pos<=mid)insert(t[root].lc,t[pre].lc,l,mid,pos);
        else insert(t[root].rc,t[pre].rc,mid+1,r,pos);
    }
    int query(int x,int y,int l,int r,int k)
    {
        if(l==r)return l;
        int mid=(l+r)/2;
        int sum=t[t[y].lc].sum-t[t[x].lc].sum;
        if(k<=sum)return query(t[x].lc,t[y].lc,l,mid,k);
        else return query(t[x].rc,t[y].rc,mid+1,r,k-sum);
    }
    int main()
    {
        freopen("jh.in","r",stdin);
        n=read();m=read();
        for(int i=1;i<=n;i++)
        {
            a[i]=read();
            co[i]=a[i];
        }
        sort(co+1,co+1+n);
        int num=unique(co+1,co+n+1)-co-1;
        for(int i=1;i<=n;i++)
        {
            int pos=lower_bound(co+1,co+num+1,a[i])-co;
            insert(root[i],root[i-1],1,num,pos);
        }
        for(int i=1;i<=m;i++)
        {
            int l=read(),r=read(),k=(l+r)/2-l+1;
            int pos=query(root[l-1],root[r],1,num,k);
            printf("%d
    ",co[pos]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    equals(),hashcode(),克隆学习心得
    AOP学习心得&jdk动态代理与cglib比较
    jackson注解使用心得
    rabbitmq使用心得
    web项目存数据到数据库,中文乱码,解决过程
    jdk动态代理学习
    团队作业——随堂小测(同学录)基本完工-紫仪
    alpha-咸鱼冲刺day3-紫仪
    alpha-咸鱼冲刺day2-紫仪
    alpha-咸鱼冲刺day1-紫仪
  • 原文地址:https://www.cnblogs.com/harden/p/5860411.html
Copyright © 2020-2023  润新知