zoukankan      html  css  js  c++  java
  • POJ_2104 K-th Number 【主席树】

    一 题面

      K-th Number

    二 分析

      第一个主席树的题,感触蛮多吧,几个关键点就是可持久化数据结构,这里的主席树其实就是保留了之前各个版本的权值线段树,然后利用权值线段树和历史版本可以进行相加减的优势,实现了第K小。

    三 AC代码

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <vector>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 const int MAXN = 1e5 + 15;
     8 const int N = MAXN * 30;
     9 
    10 int n, m, tot, len;
    11 int a[MAXN], b[MAXN];
    12 int T[N], lson[N], rson[N], sum[N];
    13 //进行离散化
    14 int getID(int val)
    15 {
    16     return lower_bound(b + 1, b + n + 1, val) - b;
    17 }
    18 //初始化,如果追求速度,可以进行优化
    19 void build(int &root, int l, int r)
    20 {
    21     root = tot++;
    22     if(l == r)
    23         return;
    24     sum[root] = 0;
    25     int mid = (l + r) >> 1;
    26     build(lson[root], l, mid);
    27     build(rson[root], mid + 1, r);
    28 }
    29 //构造新版本的权值线段树
    30 void update(int &cur, int pre, int l, int r, int val)
    31 {
    32     cur = tot++;
    33     lson[cur] = lson[pre];
    34     rson[cur] = rson[pre];
    35     sum[cur] = sum[pre] + 1;
    36     if(l == r)  return;
    37     int mid = (l + r) >> 1;
    38     if(val <= mid)  update(lson[cur], lson[pre], l, mid, val);
    39     else    update(rson[cur], rson[pre], mid + 1, r, val);
    40 }
    41 //询问第K小
    42 int query(int x, int y, int l, int r, int k)
    43 {
    44     if(l == r)
    45         return l;
    46     int mid = (l + r) >> 1;
    47     int res = sum[lson[y]] - sum[lson[x]];
    48     if(res >= k)    return query(lson[x], lson[y], l, mid, k);
    49     else    return query(rson[x], rson[y], mid + 1, r, k - res);
    50 }
    51 int main()
    52 {
    53     scanf("%d %d", &n, &m);
    54     for(int i = 1; i <= n; i++)
    55     {
    56         scanf("%d", &a[i]);
    57         b[i] = a[i];
    58     }
    59     sort(b + 1, b + n + 1);
    60     len = unique(b + 1, b + n + 1) - b - 1;
    61     tot = 0;
    62     build(T[0], 1, len);
    63     for(int i = 1; i <= n; i++)
    64     {
    65         update(T[i], T[i-1], 1, len, getID(a[i])); 
    66     }
    67     while(m--)
    68     {
    69         int l, r, k;
    70         scanf("%d %d %d", &l, &r, &k);
    71         printf("%d
    ", b[query(T[l - 1], T[r], 1, len, k)]);
    72     }
    73     return 0;
    74 }
  • 相关阅读:
    看雪-课程-加密与解密基础
    Windows API-Wininet&WinHTTP
    OS-Windows-bat-不等待当前命令返回继续执行后续指令
    Code-OPC DA- OPC Client Code Demo
    OS-Windows-Close Windows Error Reporting
    C-长度修饰符
    Code-Linux-time_t
    Windows-bat-Path
    Code-C++-CTime&ColeDateTime
    c++命名规范、代码规范和参数设置
  • 原文地址:https://www.cnblogs.com/dybala21/p/10800926.html
Copyright © 2011-2022 走看看