LIS的树状数组实现

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int C[1100];
const int MAXN = 10;
void update(int x, int ans)
{
    C[x] = ans ;
    while(x < MAXN){
        C[x] = max(C[x] , ans) ;
        x += x&-x;
    }
}

int query(int x)
{
    int ret = 0;
    while(x > 0){
        ret = max(ret,C[x]);
        x -= x&-x;
    }
    return ret;
}

int main()
{
    int n;
    int a[1100];
    int b[1100];
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        b[i] = a[i] ;
    }
    sort (b+1 , b+1+n) ;
    //int sz = unique(b+1 , b+1+n) - b; ;
    for (int i = 1 ; i <= n ; i ++){
        a[i] = lower_bound (b+1,b+1+n,a[i]) - b ;
    }
    for(int i = 1; i <= n; i++)
       printf("%d ", a[i]); 

    int ans = 0;
    for(int i = 1; i <= n; i++){
        ans = max(ans, query(a[i]-1)+1);
        if (ans > C[a[i]])
        update(a[i] , ans) ;
    }
    printf("%d\n", ans);
    return 0;
}

  

时间: 2024-10-12 20:35:03

LIS的树状数组实现的相关文章

Codeforces Round #277 E. LIS of Sequence(486E) 树状数组乱搞

http://codeforces.com/contest/486/problem/E E. LIS of Sequence time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output The next "Data Structures and Algorithms" lesson will be about Longest I

Codeforces 486E LIS of Sequence --树状数组

题意: 一个序列可能有多个最长子序列,现在问每个元素是以下三个种类的哪一类: 1.不属于任何一个最长子序列 2.属于其中某些但不是全部最长子序列 3.属于全部最长子序列 解法: 我们先求出dp1[i]表示1~i 的最长递增子序列长度, dp2[i]表示 n~i 的最长递减子序列长度(严格增减),这里我们可以用维护最大值的树状数组来解决,开始还以为要用nlogn求LIS的那种算法,当然那样应该也可以,这里元素值是1~10^5的,可以直接用树状数组,如果元素值任意的话,我们离散化一下也可以用树状数组

【转】关于LIS和一类可以用树状数组优化的DP 预备知识

原文链接 http://www.cnblogs.com/liu-runda/p/6193690.html 预备知识 DP(Dynamic Programming):一种以无后效性的状态转移为基础的算法,我们可以将其不严谨地先理解为递推.例如斐波那契数列的递推求法可以不严谨地认为是DP.当然DP的状态也可以是二维/三维的,某一维的含义也不仅仅是指某个数列的第几项. 树状数组(BIT or fenwick tree):一种高效地动态维护一个序列并动态求取前缀和的数据结构.修改某个元素/求一次前缀和的

[noip科普]关于LIS和一类可以用树状数组优化的DP

预备知识 DP(Dynamic Programming):一种以无后效性的状态转移为基础的算法,我们可以将其不严谨地先理解为递推.例如斐波那契数列的递推求法可以不严谨地认为是DP.当然DP的状态也可以是二维/三维的,某一维的含义也不仅仅是指某个数列的第几项. 树状数组(BIT or fenwick tree):一种高效地动态维护一个序列并动态求取前缀和的数据结构.修改某个元素/求一次前缀和的时间复杂度均为O(logn) 2 LIS 好了现在假设你们都会打树状数组了(如果不会的话,baidu一发吧

【Codeforces】Gym 101156E Longest Increasing Subsequences LIS+树状数组

题意 给定$n$个数,求最长上升子序列的方案数 根据数据范围要求是$O(n\log n)$ 朴素的dp方程式$f_i=max(f_j+1),a_i>a_j$,所以记方案数为$v_i$,则$v_i=v_i+v_j,(f_i=f_j+1)$,利用lis的$O(n\log n)$树状数组做法同时维护长度和方案数 从通酱博客里还看到更详尽的解释:stackoverflow 时间复杂度$O(n\log n)$ 代码 #include <bits/stdc++.h> using namespace

poj1631——树状数组求LIS

题目:http://poj.org/problem?id=1631 求LIS即可,我使用了树状数组. 代码如下: #include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,p,a[40005],f[40005]; int query(int x) { int ret=0; for(;x;x-=x&-x) ret=max(ret,f[x]); return re

LIS 树状数组优化

lis 众所周知 即最长上升子序列 可以用dp求解 复杂度O(n^2) 我们考虑优化 用树状数组(或者线段树) 树状数组维护区间最大值 (省去原始O(n^2)算法中的查找) 这样还能求出以i结尾的lis 二分只能求出当前序列的lis (许多题里要求lis个数什么的qwq 总之比二分方便 除了码量长) 还有一个小点就是可能会用到离散化(传送门) 具体实现看代码 #include<bits/stdc++.h> using namespace std; int a[mxn],b[mxn],n,sz,

UvaLive 6667 Longest Chain (分治求三元组LIS&amp;树状数组)

题目链接: here 题意: 和hdu4742类似.区别就是一部分三元组是直接给出的.还有一部分是用他给的那个函数生成的.还有就是这里的大于是严格的大于a>b必须ax>bx,ay>by,az>bz. 思路: 思路也和hdu4742here类似.只是有几个比较棘手的问题.现在变成严格大于了.对于y还是很好办的.我们在排序y的时候可以使的标号大的排在前面这样就可以防止y和它一样的更新它了.感觉比较麻烦的是x一样怎么办.这个真没想出什么好办法.就只有x和mid+1的x不一样的建一个树状数

树状数组求LIS

我真的是咸鱼啊 多少年前的基础了我竟然才弄明白,哭 用树状数组维护<=x的最上上升子序列的最大值即可啊Orz 我真的菜的一笔啊! #include <bits/stdc++.h> using namespace std; map<int,int>mp; int f[50005],n,t[50005]; void modify(int x,int Max){ for(int i=x;i<=50004;i+=x&-x) { t[i]=max(t[i],Max); }