bzoj5157: [Tjoi2014]上升子序列(树状数组LIS)

Posted CHerish_OI

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj5157: [Tjoi2014]上升子序列(树状数组LIS)相关的知识,希望对你有一定的参考价值。

5157: [Tjoi2014]上升子序列

题目:传送门


 

题解:

   学一下nlogn的树状数组求最长上生子序列就ok

   离散化之后,用一个数组记录一下,直接树状数组做

   吐槽:妈耶...一开始不会lower_bound 的蒟蒻用手打二分离散化...结果去重了...然后屁颠屁颠的学了lower_bound(很好用!)

 


代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define mod 1000000007
using namespace std;
int n,a[110000],wa[110000],s[110000];
int lowbit(int x){return x&-x;}
void add(int x,int p)
{
    while(x<=n)
    {
        s[x]=(s[x]+p)%mod;
        x+=lowbit(x);
    }
}
int getsum(int x)
{
    int ans=0;
    while(x)
    {
        ans=(ans+s[x])%mod;
        x-=lowbit(x);
    }
    return ans;
}/*
int LS(int x)
{
    int l,r,mid,ans;
    l=1,r=n;
    while(l<=r)
    {
        mid=(l+r)/2;
        if(wa[mid]<=x)
        {
            l=mid+1;
            ans=mid;
        }
        else r=mid-1;
    }
    return ans;
}*/
int v[110000],last[110000],pos[110000];
int main()
{
    scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]),wa[i]=a[i];
    sort(wa+1,wa+n+1);int sum=0;
    for(int i=1;i<=n;i++)
    {
        a[i]=lower_bound(wa+1,wa+n+1,a[i])-wa;
        if(pos[a[i]]==0)sum++;
        last[i]=pos[a[i]];pos[a[i]]=i;
    }
    for(int i=1;i<=n;i++)
    {
        v[i]=getsum(a[i]-1)+1;//这个数能贡献的上升子序列个数 
        add(a[i],(v[i]-v[last[i]]+mod)%mod);//减去重复的贡献 
    }
    int ans=getsum(n);
    printf("%d\n",(ans-sum+mod)%mod);
    return 0;
}

 

以上是关于bzoj5157: [Tjoi2014]上升子序列(树状数组LIS)的主要内容,如果未能解决你的问题,请参考以下文章

[BZOJ3173][Tjoi2013]最长上升子序列

bzoj3173 [Tjoi2013]最长上升子序列

BZOJ3173: [Tjoi2013]最长上升子序列

BZOJ 3173: [Tjoi2013]最长上升子序列 [splay DP]

BZOJ3173: [Tjoi2013]最长上升子序列(树状数组)

[bzoj5158][Tjoi2014]Alice and Bob