标签:
题目链接:点击打开链接
题意描述:给定一个序列,找出其中递增子序列的数量?
解题思路:
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 1000000007 using 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; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
hdu 2227Find the nondecreasing subsequences(树状数组+dp+离散化)
标签:
原文地址:http://blog.csdn.net/mengxingyuanlove/article/details/48052291