zoukankan      html  css  js  c++  java
  • K-th Number

    K-th Number

    此处输入链接的描述

    题意

    给定一个序列(a1,a2,a3...,an),和m个三元组表示的查询.对于每个查询((i,j,k)),输出(ai,ai+1,...aj)的升序排列中的第(k)个数。
    思路:
    平方分割;
    如果(x)是第(k)个数,那么有

    • 在区间中不超过x的数不少于k个
    • 在区间中小于x的数有不到k个
      那分整个数来判断当前的数是否符合区间中的第k小数,因为二分的是整个区间所以假设当前二分的数字比要求的数字大并且不在当前区间中那么因为二分是取最小的符合要求的,所以不会选到这个不符合要求的数,如果当前数(s)小于所要求的数并且符合为第k小的数且不在要求的区间内,这样的数是不存在的,假设符合要求的数是(t),那么在区间中有k个数小于等于(t)这些数中包括他自己,所以如果是(s)的话他就不可能有k个数小于等于(s),所以可以整体二分.
      分块处理:
    • 对于完全包含在区间内的桶,用二分搜索法计算.
    • 对于所在的桶不完全包含在区间内的元素,逐个检查.
      复杂度分析见白书.
    #include<stdio.h>
    #include<algorithm>
    #include<iostream>
    #include<string.h>
    #include<math.h>
    #include<queue>
    #include<vector>
    using namespace std;
    typedef long long LL;
    const LL mod = 1e9+7;
    int a[100005];
    vector<int>vec[100005];
    int num[100005];
    const int BufferSize=1<<16;
    char buffer[BufferSize],*head,*tail;
    inline char Getchar()
    {
        if(head==tail)
        {
            int l=fread(buffer,1,BufferSize,stdin);
            tail=(head=buffer)+l;
        }
        return *head++;
    }
    inline int read()
    {
        int x=0,f=1;
        char c=Getchar();
        for(; !isdigit(c); c=Getchar()) if(c=='-') f=-1;
        for(; isdigit(c); c=Getchar()) x=x*10+c-'0';
        return x*f;
    }
    int main(void)
    {
        int n,m;
        scanf("%d %d",&n,&m);
        for(int i = 0; i < n; i++)
            scanf("%d",&a[i]);
        int c = 1000;
        int cn = 1;
        for(int i = 0; i < n; i++)
        {
            num[i] = a[i];
            if(i < c*cn)
                vec[cn-1].push_back(a[i]);
            else
            {
                cn++;
                vec[cn-1].push_back(a[i]);
                sort(vec[cn-2].begin(),vec[cn-2].end());
            }
        }
        sort(vec[cn-1].begin(),vec[cn-1].end());
        sort(num,num+n);
        a[n] = 1e9;
        for(int i = 0; i < m; i++)
        {
            int ll,rr,k;
            scanf("%d",&ll),scanf("%d",&rr),scanf("%d",&k);
            ll--,rr--;
            int l = 0,r = n-1;
            int ask = 0;
            while(l <= r)
            {
                int mid = (l+r)/2;
                int d = num[mid];
                int tl  = ll,tr = rr,sum = 0;
                while(tl <= tr&&tl%c!=0)if(a[tl++] <= d)sum++;
                while(tl <= tr&&tr%c!=0)if(a[tr--] <= d)sum++;
                if(a[tr] <= d&&tl <= tr)sum++;
                tr--;
                while(tl <= tr)
                {
                    int u = tl/c;
                    int lll = 0,rrr = vec[u].size()-1;
                    int id = -1;
                    while(lll <= rrr)
                    {
                        int ic = (lll+rrr)/2;
                        if(vec[u][ic] <= d)
                        {
                            id = ic;
                            lll = ic + 1;
                        }
                        else rrr = ic - 1;
                    }
                    sum += id + 1;
                    tl += c;
                }
                if(sum >= k)
                    ask = mid,r = mid - 1;
                else l = mid + 1;
            }
            printf("%d
    ",num[ask]);
        }
        return 0;
    }
    
  • 相关阅读:
    VINS bug 调试 : undefined reference to `cv::FileStorage::FileStorage(std::__cxx11::basic_string<char, std::char_traits<char>,
    Fundamental Matrix
    const和指针数组
    结构体的嵌套,结构体内定义结构体。
    第4章:动态规划
    第3章:有限马尔科夫决策过程
    吴恩达深度学习中reshape图片数据的用法
    Logistic 回归Loss函数与交叉熵、极大似然估计 关系
    Logistic 回归(吴恩达)
    强化学习Sutton (Reinforcement Learning : An introduction )文章概括和总结
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/6873503.html
Copyright © 2011-2022 走看看