• 51nod 第K大区间2(二分+树状数组)


    题目链接:

    第K大区间2

    基准时间限制:1.5 秒 空间限制:131072 KB 分值: 160

    定义一个长度为奇数的区间的值为其所包含的的元素的中位数。中位数_百度百科 

    现给出n个数,求将所有长度为奇数的区间的值排序后,第K大的值为多少。

    样例解释:


    [l,r]表示区间的值
    [1]:3
    [2]:1
    [3]:2
    [4]:4
    [1,3]:2
    [2,4]:2


    第三大是2

    Input
    第一行两个数n和k(1<=n<=100000,k<=奇数区间的数量)
    第二行n个数,0<=每个数<2^31
    Output
    一个数表示答案。
    Input示例
    4 3
    3 1 2 4
    Output示例
    2

    题意:


    思路:

    二分答案t,统计中位数大于等于t的区间有多少个。
    设a[i]为前i个数中有a[i]个数>=t,若奇数区间[l,r]的中位数>=t,则(a[r]-a[l-1])*2>r-l+1,即(a[r]*2-r)>(a[l-1]*2-l+1)。
    设b[i]=a[i]*2-i,统计每个b[i]有多少个b[j]<b[i](j<i 且 j和i奇偶性不同)
    总复杂度O(nlognlogn)



    AC代码:

    //#include <bits/stdc++.h>
    #include <vector>
    #include <iostream>
    #include <queue>
    #include <cmath>
    #include <map>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    
    using namespace std;
    #define Riep(n) for(int i=1;i<=n;i++)
    #define Riop(n) for(int i=0;i<n;i++)
    #define Rjep(n) for(int j=1;j<=n;j++)
    #define Rjop(n) for(int j=0;j<n;j++)
    #define mst(ss,b) memset(ss,b,sizeof(ss));
    typedef long long LL;
    template<class T> void read(T&num) {
        char CH; bool F=false;
        for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
        for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
        F && (num=-num);
    }
    int stk[70], tp;
    template<class T> inline void print(T p) {
        if(!p) { puts("0"); return; }
        while(p) stk[++ tp] = p%10, p/=10;
        while(tp) putchar(stk[tp--] + '0');
        putchar('
    ');
    }
    
    const LL mod=1e9+7;
    const double PI=acos(-1.0);
    const LL inf=1e10;
    const int N=1e5+15;
    
    int n,k;
    int a[N],b[N],sum[2][N];
    
    int lowbit(int x)
    {
        return x&(-x);
    }
    void update(int x,int flag)
    {
        while(x<=n)
        {
            sum[flag][x]++;
            x+=lowbit(x);
        }
    }
    int query(int x,int flag)
    {
        int s=0;
        while(x>0)
        {
            s+=sum[flag][x];
            x-=lowbit(x);
        }
        return  s;
    }
    
    
    
    struct node
    {
        int temp,pos,id;
    }po[N];
    int cmp1(node x,node y)
    {
        if(x.temp==y.temp)return x.pos<y.pos;
        return x.temp<y.temp;
    }
    int cmp2(node x,node y)
    {
        return x.pos<y.pos;
    }
    int check(LL x)
    {
        mst(sum,0);
        Riep(n)
        {
            b[i]=b[i-1]+(a[i]>=x?1:0);
            po[i].temp=2*b[i]-i;
            po[i].pos=i;
        }
        sort(po+1,po+n+1,cmp1);
        Riep(n)po[i].id=i;
        sort(po+1,po+n+1,cmp2);
        LL ans=0;
        Riep(n)
        {
            if(po[i].temp>0&&i%2==1)ans++;//包括0的;
            ans=ans+query(po[i].id,i&1^1);
            update(po[i].id,i&1);
        }
        if(ans>=k)return 1;
        return 0;
    }
    
    int main()
    {
          read(n);read(k);
          Riep(n)read(a[i]);
          LL l=1,r=inf;
          while(l<=r)
          {
              LL mid=(l+r)>>1;
              if(check(mid))l=mid+1;
              else r=mid-1;
          }
          print(l-1);
        return 0;
    }
  • 相关阅读:
    将Python的Django框架与认证系统整合的方法
    将Python的Django框架与认证系统整合的方法
    Python的Asyncore异步Socket模块及实现端口转发的例子
    每天一个linux命令(3):du命令
    每天一个linux命令(2):file 命令
    Ubantu 使用extundelete恢复数据
    ubantu 单用户模式进入系统
    GDB 调试解析
    服务器搭建5 Samba实现文件共享
    服务器搭建4 安装其它库
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5547748.html
Copyright © 2020-2023  润新知