zoukankan      html  css  js  c++  java
  • poj 2104 Kth Number(可持久化线段树)

    http://poj.org/problem?id=2104

      这是我第二次写这题了,原因只前两天看了可持久化数据结构的论文,看到线段树用可持久化的方式来写可以完成这题,于是在我构思好以后就一气呵成的把这题打了出来。一打出来就顺利通过了编译,不过刚开始的时候忘记将新建的结点的两个指针都赋值,所以稍稍debug了一下这个小问题。交上去以后RE了几次,原因是我的hash写烂了。在我改过来以后又变成TLE了,于是我就改成了模拟分配内存。。。。。几经周折,终于AC了!

      这个题感觉如果是用可持久化来写,思路比较容易理清,不用像划分树复杂的位置运算,也不用像树套树那样动则200行代码。

    代码如下:

    View Code
      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <algorithm>
      5 #include <cassert>
      6 
      7 using namespace std;
      8 
      9 const int maxn = 100005;
     10 const int HASH = 0x55555555;
     11 const int hashSize = 400009;
     12 
     13 int hash[hashSize], hashPos[hashSize];
     14 
     15 void initHash() {
     16     memset(hashPos, -1, sizeof(hashPos));
     17 }
     18 
     19 void insHash(int x, int pos) {
     20     int p = (x ^ HASH) % hashSize;
     21 
     22     if (p < 0) p += hashSize;
     23     while (hash[p] != x && ~hashPos[p]) {
     24         p = (p + 1) % hashSize;
     25     }
     26 
     27     hash[p] = x;
     28     hashPos[p] = pos;
     29 }
     30 
     31 int getPos(int x) {
     32     int p = (x ^ HASH) % hashSize;
     33 
     34     if (p < 0) p += hashSize;
     35     while (hash[p] != x && ~hashPos[p]) {
     36         p = (p + 1) % hashSize;
     37     }
     38 
     39     return hashPos[p];
     40 }
     41 
     42 int buf[maxn], num[maxn];
     43 int cntNode;
     44 struct Node {
     45     int cnt;
     46 //    Node *left, *right;
     47     int left, right;
     48 
     49     Node(int _cnt = 0) {
     50         cnt = _cnt;
     51 //        left = right = NULL;
     52         left = right = 0;
     53     }
     54 //} *Root[maxn], *Null;
     55 } node[maxn << 5];
     56 int Root[maxn];
     57 
     58 
     59 void input(int n) {
     60     memset(Root, 0, sizeof(Root));
     61     cntNode = 0;
     62 //    Null = new Node();
     63     node[0] = Node();
     64     for (int i = 1; i <= n; i++) {
     65         scanf("%d", &buf[i]);
     66         num[i] = buf[i];
     67     }
     68     sort(num + 1, num + n + 1);
     69 
     70     initHash();
     71     for (int i = 1; i <= n; i++) {
     72         insHash(num[i], i);
     73     }
     74 }
     75 
     76 //void up(Node *rt) {
     77 void up(int rt) {
     78 //    rt->cnt = rt->left->cnt + rt->right->cnt;
     79     node[rt].cnt = node[node[rt].left].cnt + node[node[rt].right].cnt;
     80 }
     81 
     82 //#define lson l, m, rt->left
     83 //#define rson m + 1, r, rt->right
     84 #define lson l, m, node[rt].left
     85 #define rson m + 1, r, node[rt].right
     86 
     87 //void build(int l, int r, Node *&rt) {
     88 void build(int l, int r, int &rt) {
     89 //    rt = new Node();
     90     rt = ++cntNode;
     91     node[rt] = Node();
     92     if (l == r) {
     93 //        rt->left = rt->right = Null;
     94         return ;
     95     }
     96     int m = (l + r) >> 1;
     97 
     98     build(lson);
     99     build(rson);
    100     up(rt);
    101 }
    102 
    103 //void update(int x, int l, int r, Node *rt, Node *&newRt) {
    104 void update(int x, int l, int r, int rt, int &newRt) {
    105     if (l == r) {
    106 //        newRt = new Node(rt->cnt + 1);
    107         newRt = ++cntNode;
    108         node[newRt] = Node(node[rt].cnt + 1);
    109 //        newRt->left =newRt->right = Null;
    110 
    111         return ;
    112     }
    113     int m = (l + r) >> 1;
    114 
    115 //    newRt = new Node();
    116     newRt = ++cntNode;
    117     node[newRt] = Node();
    118 //    puts("???");
    119     if (x <= m) {
    120 //        update(x, lson, newRt->left);
    121 //        newRt->right = rt->right;
    122         update(x, lson, node[newRt].left);
    123         node[newRt].right = node[rt].right;
    124     } else {
    125 //        update(x, rson, newRt->right);
    126 //        newRt->left = rt->left;
    127         update(x, rson, node[newRt].right);
    128         node[newRt].left = node[rt].left;
    129     }
    130     up(newRt);
    131 }
    132 
    133 //#define l2son l, m, rt1->left, rt2->left
    134 //#define r2son m + 1, r, rt1->right, rt2->right
    135 #define l2son l, m, node[rt1].left, node[rt2].left
    136 #define r2son m + 1, r, node[rt1].right, node[rt2].right
    137 
    138 //int query(int k, int l, int r, Node *rt1, Node *rt2) {
    139 int query(int k, int l, int r, int rt1, int rt2) {
    140     if (l == r) {
    141         return num[l];
    142     }
    143     int m = (l + r) >> 1;
    144 //    int cnt = rt2->left->cnt - rt1->left->cnt;
    145     int cnt = node[node[rt2].left].cnt - node[node[rt1].left].cnt;
    146 
    147 //    assert(0 <= cnt && cnt <= r - l + 1);
    148     if (k <= cnt) {
    149         return query(k, l2son);
    150     } else {
    151         return query(k - cnt, r2son);
    152     }
    153 }
    154 
    155 int segK(int l, int r, int k, int n) {
    156     return query(k, 1, n, Root[l - 1], Root[r]);
    157 }
    158 /*
    159 void printTree(Node *rt) {
    160     if (!rt) return ;
    161     putchar('(');
    162     printTree(rt->left);
    163     printf("%d", rt->cnt);
    164     printTree(rt->right);
    165     putchar(')');
    166 }
    167 */
    168 int main() {
    169     int n, m;
    170 
    171 //    freopen("in", "r", stdin);
    172     while (~scanf("%d%d", &n, &m)) {
    173         input(n);
    174         build(1, n, Root[0]);
    175         for (int i = 1; i <= n; i++) {
    176             update(getPos(buf[i]), 1, n, Root[i - 1], Root[i]);
    177 //            printTree(Root[i]);
    178 //            puts("~~~");
    179         }
    180         while (m--) {
    181             int l, r, k;
    182 
    183             scanf("%d%d%d", &l, &r, &k);
    184             printf("%d\n", segK(l, r, k, n));
    185         }
    186     }
    187 
    188     return 0;
    189 }

    ——written by Lyon

  • 相关阅读:
    spring揭秘读书笔记----spring的ioc容器之BeanFactory
    spring启动加载过程源码分析
    java线程数过高原因分析
    spring揭秘读书笔记----ioc的基本概念
    git merge rebase的区别及应用场景
    spring实现定时任务
    jetty.xml解析
    Hackthebox--------irked
    CTF之信息泄漏
    CTF web题型解题技巧
  • 原文地址:https://www.cnblogs.com/LyonLys/p/poj_2104_Lyon.html
Copyright © 2011-2022 走看看