【树状数组】 HDU 4991 Ordered Subsequence
DP+树状数组
dp [i] [j] i 表示第i个数 j表示第j大的数 1<= j <=m
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <string> #include <iostream> #include <algorithm> #include <sstream> using namespace std; #include <queue> #include <stack> #include <vector> #include <deque> #include <set> #include <map> #define cler(arr, val) memset(arr, val, sizeof(arr)) #define IN freopen ("in.txt" , "r" , stdin); #define OUT freopen ("out.txt" , "w" , stdout); typedef long long LL; const int MAXN = 10011;//点数的最大值 const int MAXM = 20006;//边数的最大值 const int INF = 11521204; const int mod=123456789; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int a[MAXN],b[MAXN]; void add(int &a,int b) { a+=b; if(a>=mod) a-=mod; } struct node { int n,sum[MAXN]; void init(int x) { n=x; cler(sum,0); } int lowbit(int x) { return x&(-x); } int query(int pos) { int res=0; while(pos>0) { add(res,sum[pos]); pos-=lowbit(pos); } return res; } void update(int pos,int x) { while(pos<=n) { add(sum[pos],x); pos+=lowbit(pos); } } }bit[110]; int dp[MAXN][110]; int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1; i<=n; i++) { scanf("%d",&a[i]); b[i]=a[i]; } sort(a+1,a+n+1); int cnt=unique(a+1,a+n+1)-a; for(int i=0;i<=m;i++) bit[i].init(n); cler(dp,0); bit[0].update(1,1); dp[0][0]=1; int ans=0; for(int i=1; i<=n; i++) { int x; x=lower_bound(a+1,a+cnt,b[i])-a; for(int j=1;j<=m;j++) { add(dp[i][j],bit[j-1].query(x)); bit[j].update(x+1,dp[i][j]); } add(ans,dp[i][m]); } printf("%d\n",ans); } return 0; }