您的位置:首页 > 其它

hdu 3564 Another LIS (Splay Tree OR Segment Tree)

2013-05-23 02:57 477 查看
Problem - 3564

  好不容易看见一道可以用Splay Tree写的题,结果应该是常数过大超时了。

  好不容易还是给我找到bug了,就是一个字母打错,导致超时了。splay tree可以以421ms的时间完美通过。做法就是模拟插入数字,维护区间的最大LIS值即可。

Splay版代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>

using namespace std;

#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1

const int N = 111111;
int mx[N << 2], cnt[N << 2];

void up1(int rt) {
cnt[rt] = cnt[rt << 1] + cnt[rt << 1 | 1];
}

void build1(int l, int r, int rt) {
if (l == r) {
cnt[rt] = 1;
return ;
}
int m = l + r >> 1;
build1(lson);
build1(rson);
up1(rt);
}

int ins1(int x, int l, int r, int rt) {
if (l == r) {
cnt[rt] = 0;
return l;
}
int m = l + r >> 1, ret;
if (cnt[rt << 1] >= x) {
ret = ins1(x, lson);
} else {
ret = ins1(x - cnt[rt << 1], rson);
}
up1(rt);
return ret;
}

int rec
, id
;

void PRE(int n) {
for (int i = 0; i < n; i++) scanf("%d", &rec[i]);
build1(0, n - 1, 1);
for (int i = n - 1; i >= 0; i--) id[i] = ins1(rec[i] + 1, 0, n - 1, 1);
//    for (int i = 0; i < n; i++) cout << i << " : " << id[i] << ' ' << rec[i] << endl;
}

void up2(int rt) {
mx[rt] = max(mx[rt << 1], mx[rt << 1 | 1]);
}

void build2(int l, int r, int rt) {
cnt[rt] = mx[rt] = 0;
if (l == r) return ;
int m = l + r >> 1;
build2(lson);
build2(rson);
}

void ins2(int x, int val, int l, int r, int rt) {
if (l == r) {
mx[rt] = val;
return ;
}
int m = l + r >> 1;
if (x <= m) ins2(x, val, lson);
else ins2(x, val, rson);
up2(rt);
}

int query2(int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) {
return mx[rt];
}
int m = l + r >> 1, ret = 0;
if (L <= m) ret = max(ret, query2(L, R, lson));
if (m < R) ret = max(ret, query2(L, R, rson));
return ret;
}

void work(int n) {
int tmp, curMax = 0;
build2(0, n - 1, 1);
for (int i = 0; i < n; i++) {
tmp = query2(0, id[i], 0, n - 1, 1);
curMax = max(curMax, tmp + 1);
printf("%d\n", curMax);
ins2(id[i], tmp + 1, 0, n - 1, 1);
}
}

int main() {
//    freopen("in", "r", stdin);
int T, n;
scanf("%d", &T);
for (int i = 1; i <= T; i++) {
scanf("%d", &n);
printf("Case #%d:\n", i);
PRE(n);
work(n);
puts("");
}
return 0;
}


View Code

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