• poj 2104


    区间第K小 刚刚学的划分树

    感觉树的作用就是 n^2  -> n logn

    分治一下  划分成左右2个子树 然后小的左边  大的右边

    #include <iostream>
    #include<string.h>
    #include<stdio.h>
    #include<algorithm>
    #include<string>
    #include<math.h>
    
    using namespace std ;
    
    #define e 2.7182818284
    #define LL __int64
    #define MAXN 200010
    #define inf  1000000000
    
    struct node
    {
        int val[MAXN];//当前这一层的第i个位置的值
        int num[MAXN];//到i这个位子应该进入左子树的数目
    }t[20];           //划分成左右的化不会超过20层
    int sorted[MAXN]; //排序后的数组
    void Build(int l,int r,int ind) //建树  左右区间 然后层数
    {
        if(l==r)
            return ;
        int mid=(l+r)>>1;
        int lsame = mid-l+1,same=0,ln=l,rn=mid+1;//lsame 代表到左子树的数目  下面有用  其实是算出到左边满了没有
        for(int i=l;i<=r;i++)
            if(t[ind].val[i]<sorted[mid]) //小的话显然是要去的
                lsame--;
        for(int i=l;i<=r;i++)
        {
            if(i==l)
                t[ind].num[i]=0;
            else
                t[ind].num[i]+=t[ind].num[i-1];
            if(t[ind].val[i]<sorted[mid])
                t[ind].num[i]++,t[ind+1].val[ln++]=t[ind].val[i];//小的话去左边 然后左子树的值附上
            else if(t[ind].val[i]>sorted[mid])
                t[ind+1].val[rn++]=t[ind].val[i];
            else
            {
                same++;
                if(lsame>=same)
                    t[ind].num[i]++,t[ind+1].val[ln++]=t[ind].val[i]; //这边是左边还能去
                else
                    t[ind+1].val[rn++] = t[ind].val[i];
            }
        }
        Build(l,mid,ind+1);
        Build(mid+1,r,ind+1);
    }
    int ques(int st, int ed, int k, int l,int r, int ind)
    {
        if(l==r)
            return t[ind].val[l];
        int lx,ly,rx,ry,mid = (l + r)>>1;
        if(st == l)
            lx = 0, ly = t[ind].num[ed];
        else
            lx = t[ind].num[st - 1],ly = t[ind].num[ed] - t[ind].num[st - 1];
    if(ly >= k) //左子树大了 { st = l + lx; ed = l + lx + ly -1; return ques(st,ed,k,l,mid, ind+1); } else //去掉左子树的那段 从右边那段开始 { rx = st - 1 - l + 1 - lx; ry = ed - st + 1 - ly; st = mid + 1 + rx; ed = mid + 1 + rx + ry - 1; return ques(st,ed,k - ly, mid + 1,r,ind + 1); } } int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&sorted[i]); t[0].val[i]=sorted[i]; } sort(sorted+1,sorted+n+1); Build(1,n,0); while(m--) { int a,b,c; scanf("%d%d%d",&a,&b,&c); int ans=ques(a,b,c,1,n,0); printf("%d ",ans); } return 0; }
  • 相关阅读:
    Android Studio 插件(不定期更新)
    Spring 之 @ComponentScan以及mock Spring MVC
    Spring MVC 之传递模型数据到视图中
    开发笔记
    最小可用 Spring MVC 配置
    Spring 之定义切面尝试(基于 XML)
    Spring 之定义切面尝试(基于注解)
    Spring 之高级装配
    Spring 之混合配置
    Spring 之通过 XML 装配 bean
  • 原文地址:https://www.cnblogs.com/cherryMJY/p/6500798.html
Copyright © 2020-2023  润新知