HDU 2227-Find the nondecreasing subsequences(dp+BIT优化)

题意:

给你一个序列a[],求它的不降子序列的个数

分析:

dp[i]表示以i结尾不降子序列的个数,dp[i]=sum(dp[j])+1(j<i&&a[j]<=a[i]);答案就是sum(dp[i])

但发现一个问题n很大O(n^2)肯定超时,想起前面做的两道题,用线段树优化,它是用维护的是和,可以用BIT优化,但又发现a[i]的值很大没法存,就又想到了离散化,恩这个题就解决了。

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <string>
#include <cctype>
#include <complex>
#include <cassert>
#include <utility>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
#define lson l,m,rt<<1
#define pi acos(-1.0)
#define rson m+1,r,rt<<11
#define All 1,N,1
#define N 100010
#define read freopen("in.txt", "r", stdin)
const ll  INFll = 0x3f3f3f3f3f3f3f3fLL;
const int INF= 0x7ffffff;
const int mod =  1000000007;
ll a[N],bit[N],tmp[N],dp[N];
int n;
void add(int x,ll d){
    while(x<=n){
        bit[x]=(bit[x]+d)%mod;
        x+=(x&(-x));
    }
}
ll sum(int x){
    ll num=0;
    while(x>0){
        num=(num+bit[x])%mod;
        x-=(x&(-x));
    }
    return num;
}
int main()
{
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;++i){
            scanf("%I64d",&a[i]);
            tmp[i]=a[i];
        }
        sort(tmp+1,tmp+n+1);
        int len=unique(tmp+1,tmp+n+1)-tmp-1;
        /*for(int i=1;i<=len;++i)
            cout<<tmp[i]<<endl;*/
        memset(dp,0,sizeof(dp));
        memset(bit,0,sizeof(bit));
        ll total=0;
        for(int i=1;i<=n;++i){
            int pos=lower_bound(tmp+1,tmp+len+1,a[i])-tmp;
            dp[i]=1;
            dp[i]=(dp[i]+sum(pos))%mod;
            add(pos,dp[i]);
            total=(total+dp[i])%mod;
        }
        printf("%I64d\n",total);
    }
return 0;
}

 

posted on 2015-08-16 19:57  积跬步、至千里  阅读(133)  评论(0编辑  收藏  举报

导航