hdu 2227Find the nondecreasing subsequences(树状数组+dp+离散化)

来源:互联网 发布:vb winhttp 编辑:程序博客网 时间:2024/06/05 00:22

题目链接:点击打开链接

题意描述:给定一个序列,找出其中递增子序列的数量?


解题思路:

1、dp[i]:表示以元素i结尾的子序列的数量,则d[j]=sum(d[i])+1;其中(j>=i且j的下标大于i)

2、此刻我们可以联想到树状数组,按数组下标从小到大的顺序插入元素,那么d[j]就等于sum(j)+1;

3、由于数据范围比较大,我们采用离散化处理即可


代码:

#include <cstdio>#include <algorithm>#include <cstring>#define MOD 1000000007using namespace std;struct node{    long long v;    int pos;    int rv;}d[100010];int n,rv;bool cmp1(node a,node b){    if(a.v==b.v)        return a.pos<b.pos;    return a.v<b.v;}bool cmp2(node a,node b){    return a.pos<b.pos;}int C[100010];int lowbit(int x){    return x&(-x);}int sum(int x){    long long ret=0;    while(x>0){        ret+=C[x];        ret%=MOD;        x-=lowbit(x);    }    return (int)ret;}void add(int x,int v){    while(x<=rv){        C[x]=(C[x]+(long long)v)%MOD;        x+=lowbit(x);    }}int main(){    while(scanf("%d",&n)==1){        for(int i=0;i<n;++i){            scanf("%I64d",&d[i].v);            d[i].pos=i;        }        sort(d,d+n,cmp1);        rv=0;        for(int i=0;i<n;++i)            d[i].rv=++rv;        sort(d,d+n,cmp2);        memset(C,0,sizeof(C));        long long ans=0;        for(int i=0;i<n;++i){            add(d[i].rv,sum(d[i].rv-1)+1);            ans+=sum(d[i].rv-1)+1;            ans%=MOD;        }        printf("%d\n",(int)ans);    }    return 0;}


0 0
原创粉丝点击