HDU 2227 Find the nondecreasing subsequences(DP),hdunondecreasing
Problem DescriptionHow many nondecreasing subsequences can you find in the sequence S = {s1, s2, s3, ...., sn} ? For example, we assume that S = {1, 2, 3}, and you can find seven nondecreasing subsequences, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}.
InputThe input consists of multiple test cases. Each case begins with a line containing a positive integer n that is the length of the sequence S, the next line contains n integers {s1, s2, s3, ...., sn}, 1 <= n <= 100000, 0 <= si <= 2^31.
OutputFor each test case, output one line containing the number of nondecreasing subsequences you can find from the sequence S, the answer should % 1000000007.
Sample Input
31 2 3
Sample Output
7
題意:問你不降子序列的個數。一看n達到了1e5的層級。就知道得nlogn演算法。然而想到了一個mp的迭代但是每次迭代都得log複雜度太高。所以樹狀數組+離散化搞。
題解:設dp[i]為前i個並且以i結尾的的不降子序列個數。我們知道前面凡是小於等於a[i]的都可以到dp[i],所以dp[i]+=dp[j](a[j]<=a[i]&&j<i).
#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<string>#include<iostream>#include<queue>#include<cmath>#include<map>#include<stack>#include<bitset>using namespace std;#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )#define CLEAR( a , x ) memset ( a , x , sizeof a )typedef long long LL;typedef pair<int,int>pil;const int INF = 0x3f3f3f3f;const int MOD=1e9+7;const int maxn=1e5+10;int a[maxn],n,b[maxn+100];LL dp[maxn],c[maxn+100];int lowbit(int x){ return x&(-x);}void update(int x,LL val){ while(x<maxn) { c[x]=(c[x]+val)%MOD; x+=lowbit(x); }}LL query(int x){ LL sum=0; while(x>0) { sum=(sum+c[x])%MOD; x-=lowbit(x); } return sum;}int main(){ while(~scanf("%d",&n)) { int cnt=1; CLEAR(c,0); REPF(i,1,n) { scanf("%d",&a[i]); b[cnt++]=a[i]; } sort(b+1,b+cnt); cnt=unique(b+1,b+cnt)-(b+1); for(int i=1;i<=n;i++) dp[i]=1; LL ans=0; for(int i=1;i<=n;i++) { int x=lower_bound(b+1,b+1+cnt,a[i])-b; dp[i]=(dp[i]+query(x))%MOD; update(x,dp[i]); ans=(ans+dp[i])%MOD; } printf("%I64d\n",ans); } return 0;}/**/