[Tjoi2013]最长上升子序列 树状数组+二分

标签: 树状数组 二分
12人阅读 评论(0) 收藏 举报
分类:

Description
给定一个序列,初始为空。现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置。每插入一个数字,我们都想知道此时最长上升子序列长度是多少?


Sample Input
3
0 0 2


Sample Output
1
1
2


这道题首先我们的思路是求出每个数放的位置,这个过程我们倒着插,是可以二分的。
然后再考虑求最长上升子序列,用树状数组维护全局最大值。。。


#include <cstdio>
#include <cstring>

using namespace std;
int _max(int x, int y) {return x > y ? x : y;}

int n, a[110000], s[110000];

int lowbit(int x) {return x & -x;}
void change1(int x, int c) {
    for(int i = x; i <= n; i += lowbit(i)) s[i] += c;
}
void change2(int x, int c) {
    for(int i = x; i <= n; i += lowbit(i)) s[i] = _max(s[i], c);
}
int getsum(int x) {
    int sum = 0;
    for(int i = x; i >= 1; i -= lowbit(i)) sum += s[i];
    return sum;
}
int getmax(int x) {
    int maxx = 0;
    for(int i = x; i >= 1; i -= lowbit(i)) maxx = _max(maxx, s[i]);
    return maxx;
}

int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]), a[i]++;
    for(int i = n; i >= 1; i--) {
        int x = a[i];
        int l = a[i], r = n;
        while(l <= r) {
            int mid = (l + r) / 2;
            if(getsum(mid) <= mid - x) a[i] = mid, r = mid - 1;
            else l = mid + 1;
        }
        change1(a[i], 1);
    }
    int ans = 0;
    memset(s, 0, sizeof(s));
    for(int i = 1; i <= n; i++) {
        int s = getmax(a[i] - 1) + 1;
        ans = _max(ans, s);
        change2(a[i], s);
        printf("%d\n", ans);
    }
    return 0;
}
查看评论

bzoj3173【TJOI2013】最长上升子序列

二分+树状数组
  • AaronGZK
  • AaronGZK
  • 2016-04-13 22:50:04
  • 3604

[树状数组求第K大][BZOJ 3173][TJOI 2013]最长上升子序列

Description(嘛,找不到文字题面) Analysis 因为数字是从小到大插入的,所以我们可以构造出最终序列,然后O(NlogN)求最长上升子序列。 关键是构造出最终序列...
  • D_William
  • D_William
  • 2013-06-21 17:02:31
  • 1591

【bzoj3173】: [Tjoi2013]最长上升子序列

ms是个简单的splay+nlogn的最长上升子序列。。? 但是我老是搞不清顺序怎么办0.0 根据题目加入的顺序发现的性质要注意阿0.0 orzorzlyh#include #include #...
  • Qingegege
  • Qingegege
  • 2016-02-25 10:28:22
  • 413

bzoj 3173: [Tjoi2013]最长上升子序列(splay)

3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1315  Solved: 682 [Submi...
  • clover_hxy
  • clover_hxy
  • 2016-05-09 11:15:45
  • 865

hdu 3030 Increasing Speed Limits(树状数组求最长上升子序列)

在前边关于DP总结的文章中说了通过普通的DP法个二分查找法求最长上升子问题,最近在学习BIT,然后突然发现原来通过BIT也可以求最长上升子序列问题。本来想着可以通过类似的方法在O(nlogn)时间内求...
  • xueerfei008
  • xueerfei008
  • 2013-09-25 11:46:01
  • 2373

[bzoj3173][TJOI2013]最长上升子序列

题目大意共n次操作,第i次操作在第xi个数后插入数字i并询问当前最长上升子序列。 n...
  • WerKeyTom_FTD
  • WerKeyTom_FTD
  • 2016-02-14 11:30:16
  • 585

动态规划:最长上升子序列(二分算法 nlogn)

解题心得: 1、在数据量比较大的时候n^2会明显超时,所以可以使用nlogn 的算法,此算法少了双重循环,用的lower_bound(二分法)。 2、lis中的数字并没有意义,仅仅是找到最小点li...
  • yopilipala
  • yopilipala
  • 2017-03-05 16:13:33
  • 1906

[树状数组+上升子序列] HDU 3030 Increasing Speed Limits

题意:求一组数有多少严格上升子序列。以1 2 1 2 3为例,他的严格上升子序列有1 2 1 2 3 12 12 13 123 123 23 12 13 123 23 话说这个输入真的好坑,看了半天才...
  • Martin20150405
  • Martin20150405
  • 2016-02-02 14:23:52
  • 888

UVA 10534 Wavio Sequence(二分 + 最长上升子序列)

Wavio Sequence 题目: 题目大意: 题目是给一个序列,然后再其序列中找一个子序列,这个子序列符合前一半是递增的序列,后半部分是递减的序列,并且是这个序列中所有符合条...
  • xia842655187
  • xia842655187
  • 2016-05-06 17:43:04
  • 668

BZOJ 3173 Tjoi2013 最长上升子序列 Treap+树状数组

题目大意:给定一个序列,依次将1~n插入,问每次插入之后序列的LIS长度是多少 由于是从小到大插入,因此插入一个数之后显然是不影响之前的答案的 因此我们不妨先用平衡树搞出插入之后的序列,再求一遍L...
  • PoPoQQQ
  • PoPoQQQ
  • 2015-01-29 13:42:22
  • 1934
    个人资料
    持之以恒
    等级:
    访问量: 8697
    积分: 683
    排名: 7万+
    文章存档
    最新评论