zoukankan      html  css  js  c++  java
  • poj2104 K大数 划分树

    题意:给定一个数列,求一个区间的第K大数

    模板题, 其中的newl, newr 有点不明白.

     1 #include <iostream>
     2 #include <algorithm>
     3 using namespace std;
     4 const int M = 100005;
     5 int toLeft[20][M], tree[20][M], sorted[M];
     6 
     7 void build(int level, int left, int right)
     8 {
     9     if (left == right) return;
    10     int i, mid = (left + right) >>1;
    11     int suppose = mid - left + 1;
    12     for (i=left; i<=right; i++)
    13         if (tree[level][i] < sorted[mid])
    14             suppose--;
    15     int lpos = left, rpos = mid+1;
    16     for (i=left; i<=right; i++)
    17     {
    18         if (i == left)
    19             toLeft[level][i] = 0;
    20         else
    21             toLeft[level][i] = toLeft[level][i-1];
    22         if (tree[level][i] < sorted[mid])
    23         {
    24             toLeft[level][i]++;
    25             tree[level+1][lpos++] = tree[level][i];
    26         }
    27         else if (tree[level][i] > sorted[mid])
    28         {
    29             tree[level+1][rpos++] = tree[level][i];
    30         }
    31         else 
    32         {
    33             if (suppose != 0)
    34             {
    35                 suppose--;
    36                 toLeft[level][i]++;
    37                 tree[level+1][lpos++] = tree[level][i];
    38             }
    39             else
    40                 tree[level+1][rpos++] = tree[level][i];
    41         }
    42     }
    43     build(level+1, left, mid);
    44     build(level+1, mid+1, right);
    45 }
    46 
    47 int query(int level, int left, int right, int qleft, int qright, int k)
    48 {
    49     if (qleft == qright)
    50         return tree[level][qright];
    51     int s, ss, mid = (left + right)>>1;
    52     if (left == qleft)
    53     {
    54         s = 0;
    55         ss = toLeft[level][qright];
    56     }
    57     else
    58     {
    59         s = toLeft[level][qleft-1];
    60         ss = toLeft[level][qright] - s;
    61     }
    62     int newl, newr;
    63     if (k <= ss)
    64     {
    65         newl = left + s;
    66         newr = left + s + ss -1;
    67         return query(level+1, left, mid, newl, newr, k);
    68     }
    69     else
    70     {
    71         newl = mid-left+1+qleft-s;
    72         newr = mid-left+1+qright-s-ss;
    73         return query(level+1, mid+1, right, newl, newr, k-ss);
    74     }
    75 }
    76 
    77 int main()
    78 {
    79     int n, m;
    80     int i;
    81     while (scanf("%d%d", &n, &m) == 2)
    82     {
    83         for (i=1; i<=n; i++)
    84         {
    85             scanf("%d", &tree[0][i]);
    86             sorted[i] = tree[0][i];
    87         }
    88         sort(sorted+1, sorted+n+1);
    89         build(0,1,n);
    90         int ql, qr, k;
    91         for (i=0; i<m; i++)
    92         {
    93             scanf("%d%d%d", &ql, &qr, &k);
    94             printf("%d
    ", query(0, 1, n, ql, qr, k));
    95         }
    96     }
    97     return 0;
    98 }
    View Code
  • 相关阅读:
    Odoo电子数据交换(EDI)
    WMS8_仓库配置
    odoo写邮件添加收件人
    Odoo HR Payslip
    openERP邮件(发信、收信)
    Multi-company rules
    MRP Force Reservation的作用
    使用虚拟机VM运行Linux版OpenERP
    采购预付款
    消除递归的方法
  • 原文地址:https://www.cnblogs.com/lv-2012/p/3161382.html
Copyright © 2011-2022 走看看