标签:des blog http os io java ar strong for
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 114 Accepted Submission(s): 58
1003 Ordered Subsequence
首先数字有1万个,先离散化一下,把所有数字对应到1到n之间。这样对结果不影响。
dp[i][j]代表以第i个数字结尾上升子序列长度为j的种数。
dp[i][j]=sum{dp[k][j-1]} for each a[k]<a[i]&&k<i
直接写循环会超时。需要优化。
可以用平衡树进行优化,上述的循环过程可以看成是一个区间求和过程。用线段树或者树状数组可以解决。
这样最终的复杂度是n*m*log(n)
这里我用100个数组数组搞了搞,注意中间的取模
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #include<vector> #include<set> #include<stack> #include<map> #include<ctime> #define maxn 10010 #define LL long long #define INF 999999 #define mod 123456789LL using namespace std; struct node { int id; LL val; bool operator <(const node&s)const { return val < s.val ; } }qe[maxn]; LL xt[101][maxn] ; int n ,a[maxn] ; LL dp[maxn][101] ; void insert(int id,int x,int add) { while( x <= n ) { xt[id][x]+= add; if(xt[id][x] >= mod) xt[id][x] -= mod; x += (x&-x) ; } } LL sum(int id,int x) { LL ans=0; while(x >0) { ans += xt[id][x] ; if(ans>=mod) ans -= mod; x -= (x&-x) ; } return ans; } int main() { int m,i,j ; while( scanf("%d%d",&n,&m) != EOF) { for( i = 1 ; i <= n ;i++) { scanf("%I64d",&qe[i].val) ; qe[i].id= i; } sort(qe+1,qe+1+n) ; j = 1 ; a[qe[1].id] = j ; for( i = 2 ; i <= n ;i++) { if(qe[i].val==qe[i-1].val) a[qe[i].id]=j ; else a[qe[i].id] = ++j; } memset(xt,0,sizeof(xt)) ; memset(dp,0,sizeof(dp)) ; LL ans=0; for(i = 1 ; i <= n ;i++) { dp[i][1] = 1 ; for( j = 2 ; j <= m && j <= i ;j++) { dp[i][j] = sum(j-1,a[i]-1) ; } ans = (ans+dp[i][m])%mod; for( j = 1 ; j <= m && j <= i;j++) { insert(j,a[i],dp[i][j]) ; } } cout << ans << endl; } return 0 ; }
标签:des blog http os io java ar strong for
原文地址:http://www.cnblogs.com/20120125llcai/p/3961621.html