zoukankan      html  css  js  c++  java
  • POJ 2104 K-th Number(划分树)

    题目链接

    参考HH大神的模版。对其中一些转移,还没想清楚,大体明白上是怎么回事了,划分树就是类似快排,但有点点区别的。多做几个题,慢慢理解。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 using namespace std;
      5 #define lson l,m,rt<<1
      6 #define rson m+1,r,rt<<1|1
      7 #define N 100100
      8 struct node
      9 {
     10     int l,r;
     11 }tree[4*N];
     12 int sorted[N];
     13 int lnum[20][N];
     14 int val[20][N];
     15 
     16 void build(int d,int l,int r,int rt)
     17 {
     18     int m,lsame,i,lpos,rpos,same;
     19     tree[rt].l = l;
     20     tree[rt].r = r;
     21     if(l == r) return ;
     22     m = (l+r)>>1;
     23     lsame = (m - l + 1);
     24     for(i = l;i <= r;i ++)
     25     {
     26         if(val[d][i] < sorted[m])
     27         lsame --;
     28     }
     29     lpos = l;
     30     rpos = m+1;
     31     same = 0;
     32     for(i = l;i <= r;i ++)
     33     {
     34         if(i == l)//lnum[d][i]表示[tree[rt].l, i ]区域里有多少个数分到左边
     35         lnum[d][i] = 0;
     36         else
     37         lnum[d][i] = lnum[d][i-1];
     38         if(val[d][i] < sorted[m])
     39         {
     40             lnum[d][i] ++;
     41             val[d+1][lpos++] = val[d][i];
     42         }
     43         else if(val[d][i] > sorted[m])
     44         {
     45             val[d+1][rpos++] = val[d][i];
     46         }
     47         else
     48         {
     49             if(same < lsame)
     50             {
     51                 same ++;
     52                 lnum[d][i] ++;
     53                 val[d+1][lpos++] = val[d][i];
     54             }
     55             else
     56             {
     57                 val[d+1][rpos++] = val[d][i];
     58             }
     59         }
     60     }
     61     build(d+1,lson);
     62     build(d+1,rson);
     63 }
     64 int query(int d,int k,int l,int r,int rt)
     65 {
     66     int s,ss,nl,nr,m,rs,rss;//s表示[ l , r ]有多少个分到左边
     67     if(l == r)//ss表示 [tree[idx].left , l-1 ]有多少个分到左边
     68     {
     69         return val[d][l];
     70     }
     71     if(l == tree[rt].l)
     72     {
     73         s = lnum[d][r];
     74         ss = 0;
     75     }
     76     else
     77     {
     78         s = lnum[d][r] - lnum[d][l-1];
     79         ss = lnum[d][l-1];
     80     }
     81     if(s >= k)
     82     {
     83         nl = ss + tree[rt].l;
     84         nr = ss + tree[rt].l + s - 1;
     85         return query(d+1,k,nl,nr,rt<<1);
     86     }
     87     else
     88     {
     89         m = (tree[rt].l + tree[rt].r)>>1;
     90         rss = l - tree[rt].l - ss;
     91         rs = r - l + 1 - s;
     92         nl = m + rss + 1;
     93         nr = m + rs + rss;
     94         return query(d+1,k-s,nl,nr,rt<<1|1);
     95     }
     96 }
     97 int main()
     98 {
     99     int i,n,m,x,y,k;
    100     while(scanf("%d%d",&n,&m)!=EOF)
    101     {
    102         for(i = 1;i <= n;i ++)
    103         {
    104             scanf("%d",&val[0][i]);
    105             sorted[i] = val[0][i];
    106         }
    107         sort(sorted+1,sorted+n+1);
    108         build(0,1,n,1);
    109         for(i = 0;i < m;i ++)
    110         {
    111             scanf("%d%d%d",&x,&y,&k);
    112             printf("%d
    ",query(0,k,x,y,1));
    113         }
    114     }
    115     return 0;
    116 }
  • 相关阅读:
    理财技术+人生感悟(转)
    程序员每天每月每年需要做的事(转)
    数据库常用函数(数字函数)
    数据库之常用函数 (日期函数)
    Qt初级-头文件
    Qt初级-成员函数(二)
    Qt初级-成员函数(一)
    Qt初级-Qt格式(二)
    Qt初级-Qt格式(一)
    Qt初级-Qt继承表
  • 原文地址:https://www.cnblogs.com/naix-x/p/3233182.html
Copyright © 2011-2022 走看看