bzoj 3173: [Tjoi2013]最长上升子序列(离线二分+树状数组)
2017-10-04 15:51
411 查看
3173: [Tjoi2013]最长上升子序列
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2051 Solved: 1041
[Submit][Status][Discuss]
Description
给定一个序列,初始为空。现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置。每插入一个数字,我们都想知道此时最长上升子序列长度是多少?Input
第一行一个整数N,表示我们要将1到N插入序列中,接下是N个数字,第k个数字Xk,表示我们将k插入到位置Xk(0<=Xk<=k-1,1<=k<=N)Output
N行,第i行表示i插入Xi位置后序列的最长上升子序列的长度是多少。Sample Input
30 0 2
Sample Output
11
2
nlogn单调递增:http://blog.csdn.net/jaihk662/article/details/52064213
偷偷建议这题不要看题解!
……
这题的条件其实大大降低了题目难度,首先最后的序列一定是1-n的全排列
其次每次都是加上当前最大的数,这个性质很重要
这就意味着你只要得出最终的序列,然后套一下nlogn的单调递增就可以求出所有答案
令best[x]表示以数字x结尾的最长序列,ans[x]就是第x个答案
那么ans[x]=max(best[i] (1<=i<=x) )
主要是如何求出最终的序列
倒过来处理,很明显最后一个数所添加的位置一定是最终的位置,然后看下面的例子
假设样例为:
5
0 0 2 1 1
初始序列:
0 0 0 0 0(这一行就是最终序列,为0表示上面没有数字)
0 1 2 3 4(这一行表示前面有多少空位)
5加入第一个数字后面:
0 5 0 0 0
0 0 1 2 3
4加入第一个数字后面:
0 5 4 0 0
0 0 0 1
2
3加入第二个数字后面:
0 5 4 0
3
0 0 0 1 1
2加入最前面:
2 5 4 0 3
x x x 0 0(x的位置已经不可能再放数字了,可以理解为-1)
最后:
2 5 4 1 3(ok)
很显然的:树状数组维护前缀和,然后每次二分求第k个前缀最小
搞定
#include<stdio.h> #include<algorithm> using namespace std; int n, len, cha[100005], tre[100005], a[100005], best[100005], ans[100005]; void Update(int x, int val) { while(x<=n) { tre[x] += val; x += x&-x; } } int Query(int x) { int sum = 0; while(x) { sum += tre[x]; x -= x&-x; } return sum; } int Bsech(int x) { int l, r, m; l = 0, r = len; while(l<r) { m = l+(r-l)/2; if(best[m]>=x) r = m; else l = m+1; } return l; } int main(void) { int i, l, r, m, pos, now; scanf("%d", &n); for(i=1;i<=n;i++) { scanf("%d", &cha[i]); Update(i, 1); } for(i=n;i>=1;i--) { l = 1, r = n; cha[i] += 1; while(l<r) { m = (l+r)/2; if(Query(m)<cha[i]) l = m+1; else r = m; } a[r] = i; Update(r, -1); } len = 1; best[1] = a[1], ans[a[1]] = 1; for(i=2;i<=n;i++) { if(a[i]>best[len]) best[++len] = a[i], ans[a[i]] = len; else { pos = Bsech(a[i]); ans[a[i]] = pos; best[pos] = a[i]; } } now = 0; for(i=1;i<=n;i++) { now = max(now, ans[i]); printf("%d\n", now); } return 0; }
相关文章推荐
- BZOJ3173 [Tjoi2013]最长上升子序列(离线处理+Treap+LIS)
- 【BZOJ】3173: [Tjoi2013]最长上升子序列(树状数组)
- bzoj3173 [Tjoi2013]最长上升子序列(dp+splay)
- bzoj 3173: [Tjoi2013]最长上升子序列
- BZOJ3173 [Tjoi2013]最长上升子序列
- [bzoj3173][TJOI2013]最长上升子序列
- BZOJ 3173: [Tjoi2013]最长上升子序列
- BZOJ 3173 Tjoi2013 最长上升子序列 Treap+树状数组
- BZOJ3173: [Tjoi2013]最长上升子序列
- BZOJ 3173: [Tjoi2013]最长上升子序列
- 【bzoj3173】: [Tjoi2013]最长上升子序列
- 【bzoj3173】[Tjoi2013]最长上升子序列
- BZOJ3173: [Tjoi2013]最长上升子序列
- bzoj3173: [Tjoi2013]最长上升子序列
- bzoj 3173: [Tjoi2013]最长上升子序列(splay)
- BZOJ3173 [Tjoi2013]最长上升子序列
- BZOJ 3173: [Tjoi2013]最长上升子序列
- bzoj3173 [Tjoi2013]最长上升子序列
- bzoj3173 [Tjoi2013]最长上升子序列
- [树状数组求第K大][BZOJ 3173][TJOI 2013]最长上升子序列