Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 464 Accepted Submission(s): 216
Your program, when given the numeric sequence, must find the number of its ordered subsequence with exact m numbers.
Process to the end of file.
[Technical Specification]
1<=n<=10000
1<=m<=100
/** 状态转移方程: dp[i][j] = sum(dp[k][j-1]) (1<=k<i&&a[k]<a[i]) */ #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; typedef long long LL; const LL mod = 123456789; const int N = 10005; const int M = 105; int cnt,n,m; LL dp[N][M]; ///dp[i][j]代表第 i 个元素结尾,长度为 j 的递增子序列个数. LL c[N],b[N],a[N]; LL lowbit(int i){ return i&(-i); } void update(int idx,int x,LL v){ for(int i=idx;i<=cnt;i+=lowbit(i)){ dp[i][x]=(dp[i][x]+v)%mod; } } LL getsum(int idx,int x){ LL sum = 0; for(int i=idx;i>0;i-=lowbit(i)){ sum=(sum+dp[i][x])%mod; } return sum; } int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF){ for(int i=1;i<=n;i++){ scanf("%lld",&a[i]); b[i] = a[i]; } cnt = 1; for(int i=2;i<=n;i++){ ///离散化 a 数组对应树状数组的 1 - cnt if(b[i]!=b[i-1]){ b[++cnt] = b[i]; } } sort(b+1,b+cnt+1); memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++){ int idx = lower_bound(b+1,b+1+cnt,a[i])-b; for(int j=1;j<=m;j++){ LL v; if(j == 1) v = 1; else v = getsum(idx-1,j-1); update(idx,j,v); } } LL ans = getsum(cnt,m); printf("%lld\n",ans); } return 0; }
#include<cstdio> #include<string.h> #include<algorithm> using namespace std; #define LL long long const int mod=123456789; int n,m; int a[10005]; int b[10005],cnt; inline void Add(int &a,int b){ a=(a+b)%mod; } inline int lowbit(int x){ return x&(-x); } int sum[101][10005]; inline void add(int id,int x,int v){ while(x<=cnt){ Add(sum[id][x],v); x+=lowbit(x); } } inline int query(int id,int x){ int ans=0; while(x){ Add(ans,sum[id][x]); x-=lowbit(x); } return ans; } int main(){ while(~scanf("%d%d",&n,&m)){ cnt=0; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); b[++cnt]=a[i]; } sort(b+1,b+cnt+1); cnt=(int)(unique(b+1,b+1+cnt)-(b+1)); for(int i=1;i<=n;i++)a[i]=(int)(lower_bound(b+1,b+1+cnt,a[i])-b); memset(sum,0,sizeof sum); int ans=0; for(int i=1;i<=n;i++){ for(int j=0;j<m;j++){ if(a[i]>1){ int sum=query(j,a[i]-1); add(j+1,a[i],sum); } } add(1,a[i],1); } ans=query(m,cnt); printf("%d\n",ans); } return 0; }