码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2018-03-10 11:50:16      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:geo   ...   printf   targe   www.   get   树状   amp   cstring   

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)

标签:geo   ...   printf   targe   www.   get   树状   amp   cstring   

原文地址:https://www.cnblogs.com/CHerish_OI/p/8537349.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!