您的位置:首页 > 其它

BZOJ 3173 [Tjoi2013] 最长上升子序列 解题报告

2015-06-25 21:44 567 查看
这个题感觉比较简单,但却比较容易想残。。

我不会用树状数组求这个原排列,于是我只好用线段树。。。毕竟 Gromah 果弱马。

我们可以直接依次求出原排列的元素,每次找到最小并且最靠右的那个元素,假设这是第 $i$ 次找的,那么这就是原排列的第 $i$ 项,然后我们就把这个元素删去(变成很大的数),再把这个数以左的数都加 1,进行下一轮。

然后就是裸的最长上升子序列啦~~~

时间复杂度 $O(n\log n)$,空间复杂度 $O(n)$。

#include <cstdio>
#include <algorithm>
using namespace std;
#define N 100000 + 5
#define M 262144 + 5
#define ls(x) x << 1
#define rs(x) x << 1 | 1

int n, Pos
, A
, T
, F
;

struct Segment_Tree
{
int Min, delta;
}h[M];

inline void Build(int x, int l, int r)
{
if (l == r)
{
h[x].Min = Pos[l];
return ;
}
int mid = l + r >> 1;
Build(ls(x), l, mid);
Build(rs(x), mid + 1, r);
h[x].Min = min(h[ls(x)].Min, h[rs(x)].Min);
}

inline void apply(int x, int d)
{
h[x].Min += d, h[x].delta += d;
}

inline void push(int x)
{
if (h[x].delta)
{
apply(ls(x), h[x].delta);
apply(rs(x), h[x].delta);
h[x].delta = 0;
}
}

inline void Modify(int x, int l, int r, int s, int t, int d)
{
if (l == s && r == t)
{
apply(x, d);
return ;
}
push(x);
int mid = l + r >> 1;
if (t <= mid) Modify(ls(x), l, mid, s, t, d);
else if (s > mid) Modify(rs(x), mid + 1, r, s, t, d);
else Modify(ls(x), l, mid, s, mid, d), Modify(rs(x), mid + 1, r, mid + 1, t, d);
h[x].Min = min(h[ls(x)].Min, h[rs(x)].Min);
}

inline int Query(int x, int l, int r)
{
if (l == r) return l;
int mid = l + r >> 1;
if (h[rs(x)].Min <= h[ls(x)].Min)
return Query(rs(x), mid + 1, r);
else return Query(ls(x), l, mid);
}

int main()
{
#ifndef ONLINE_JUDGE
freopen("3173.in", "r", stdin);
freopen("3173.out", "w", stdout);
#endif

scanf("%d", &n);
for (int i = 1; i <= n; i ++)
scanf("%d", Pos + i);
Build(1, 1, n);
for (int i = 1; i <= n; i ++)
{
int t = Query(1, 1, n);
Modify(1, 1, n, 1, t, 1);
Modify(1, 1, n, t, t, n);
if (!T[0] || T[T[0]] < t)
{
T[++ T[0]] = t;
F[t] = T[0];
}
else
{
int x = lower_bound(T + 1, T + T[0] + 1, t) - T;
T[x] = t;
F[t] = x;
}
}
for (int i = 1, Max = 0; i <= n; i ++)
{
Max = Max > F[i] ? Max : F[i];
printf("%d\n", Max);
}

#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}


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