您的位置:首页 > 其它

poj 2104 K-th Number(可持久化线段树)

2012-10-25 13:39 411 查看
http://poj.org/problem?id=2104

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

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

代码如下:

View Code

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cassert>

using namespace std;

const int maxn = 100005;
const int HASH = 0x55555555;
const int hashSize = 400009;

int hash[hashSize], hashPos[hashSize];

void initHash() {
memset(hashPos, -1, sizeof(hashPos));
}

void insHash(int x, int pos) {
int p = (x ^ HASH) % hashSize;

if (p < 0) p += hashSize;
while (hash[p] != x && ~hashPos[p]) {
p = (p + 1) % hashSize;
}

hash[p] = x;
hashPos[p] = pos;
}

int getPos(int x) {
int p = (x ^ HASH) % hashSize;

if (p < 0) p += hashSize;
while (hash[p] != x && ~hashPos[p]) {
p = (p + 1) % hashSize;
}

return hashPos[p];
}

int buf[maxn], num[maxn];
int cntNode;
struct Node {
int cnt;
//    Node *left, *right;
int left, right;

Node(int _cnt = 0) {
cnt = _cnt;
//        left = right = NULL;
left = right = 0;
}
//} *Root[maxn], *Null;
} node[maxn << 5];
int Root[maxn];

void input(int n) {
memset(Root, 0, sizeof(Root));
cntNode = 0;
//    Null = new Node();
node[0] = Node();
for (int i = 1; i <= n; i++) {
scanf("%d", &buf[i]);
num[i] = buf[i];
}
sort(num + 1, num + n + 1);

initHash();
for (int i = 1; i <= n; i++) {
insHash(num[i], i);
}
}

//void up(Node *rt) {
void up(int rt) {
//    rt->cnt = rt->left->cnt + rt->right->cnt;
node[rt].cnt = node[node[rt].left].cnt + node[node[rt].right].cnt;
}

//#define lson l, m, rt->left
//#define rson m + 1, r, rt->right
#define lson l, m, node[rt].left
#define rson m + 1, r, node[rt].right

//void build(int l, int r, Node *&rt) {
void build(int l, int r, int &rt) {
//    rt = new Node();
rt = ++cntNode;
node[rt] = Node();
if (l == r) {
//        rt->left = rt->right = Null;
return ;
}
int m = (l + r) >> 1;

build(lson);
build(rson);
up(rt);
}

//void update(int x, int l, int r, Node *rt, Node *&newRt) {
void update(int x, int l, int r, int rt, int &newRt) {
if (l == r) {
//        newRt = new Node(rt->cnt + 1);
newRt = ++cntNode;
node[newRt] = Node(node[rt].cnt + 1);
//        newRt->left =newRt->right = Null;

return ;
}
int m = (l + r) >> 1;

//    newRt = new Node();
newRt = ++cntNode;
node[newRt] = Node();
//    puts("???");
if (x <= m) {
//        update(x, lson, newRt->left);
//        newRt->right = rt->right;
update(x, lson, node[newRt].left);
node[newRt].right = node[rt].right;
} else {
//        update(x, rson, newRt->right);
//        newRt->left = rt->left;
update(x, rson, node[newRt].right);
node[newRt].left = node[rt].left;
}
up(newRt);
}

//#define l2son l, m, rt1->left, rt2->left
//#define r2son m + 1, r, rt1->right, rt2->right
#define l2son l, m, node[rt1].left, node[rt2].left
#define r2son m + 1, r, node[rt1].right, node[rt2].right

//int query(int k, int l, int r, Node *rt1, Node *rt2) {
int query(int k, int l, int r, int rt1, int rt2) {
if (l == r) {
return num[l];
}
int m = (l + r) >> 1;
//    int cnt = rt2->left->cnt - rt1->left->cnt;
int cnt = node[node[rt2].left].cnt - node[node[rt1].left].cnt;

//    assert(0 <= cnt && cnt <= r - l + 1);
if (k <= cnt) {
return query(k, l2son);
} else {
return query(k - cnt, r2son);
}
}

int segK(int l, int r, int k, int n) {
return query(k, 1, n, Root[l - 1], Root[r]);
}
/*
void printTree(Node *rt) {
if (!rt) return ;
putchar('(');
printTree(rt->left);
printf("%d", rt->cnt);
printTree(rt->right);
putchar(')');
}
*/
int main() {
int n, m;

//    freopen("in", "r", stdin);
while (~scanf("%d%d", &n, &m)) {
input(n);
build(1, n, Root[0]);
for (int i = 1; i <= n; i++) {
update(getPos(buf[i]), 1, n, Root[i - 1], Root[i]);
//            printTree(Root[i]);
//            puts("~~~");
}
while (m--) {
int l, r, k;

scanf("%d%d%d", &l, &r, &k);
printf("%d\n", segK(l, r, k, n));
}
}

return 0;
}


——written by Lyon
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: