1. 程式人生 > >hdu6348: 序列計數

hdu6348: 序列計數

col 有一個 min pac return c++ include ase space

鑒於給定的排列是隨機的。

那麽有一個結論,最長上升子序列是$\sqrt n$級別的。

那麽我麽就可以DP了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define M 300
 4 #define MOD 1000000007
 5 int a[100010];
 6 int f[10010][310];
 7 int res[310];
 8 int n;
 9 int C[10010];
10 inline void add(int x, int y) {
11     for(int i = x; i <= n; i += (i & -i)) {
12 C[i] += y; 13 if(C[i] >= MOD) C[i] -= MOD; 14 } 15 } 16 inline int query(int x) { 17 int ret = 0; 18 for(int i = x; i; i -= (i & -i)) { 19 ret += C[i]; 20 if(ret >= MOD) ret -= MOD; 21 } 22 return ret; 23 } 24 int main() { 25 int T;
26 scanf("%d", &T); 27 for(int Ca = 1; Ca <= T; ++ Ca) { 28 scanf("%d", &n); 29 int lim = min(M, n); 30 /*for(int i = 0; i <= n; ++ i) { 31 for(int j = 1; j <= lim; ++ j) { 32 f[i][j] = 0; 33 } 34 }*/ 35 for
(int i = 1; i <= lim; ++ i) res[i] = 0; 36 for(int i = 1; i <= n; ++ i) f[i][1] = 1; 37 for(int i = 1; i <= n; ++ i) { 38 scanf("%d", &a[i]); 39 } 40 for(int k = 2; k <= lim; ++ k) { 41 for(int i = 1; i <= n; ++ i) C[i] = 0; 42 for(int i = 1; i <= n; ++ i) { 43 f[i][k] = query(a[i] - 1); 44 add(a[i], f[i][k - 1]); 45 res[k] += f[i][k]; 46 if(res[k] >= MOD) res[k] -= MOD; 47 } 48 } 49 res[1] = n; 50 printf("Case #%d: ", Ca); 51 for(int i = 1; i <= lim; ++ i) { 52 printf("%d", res[i]); 53 if(i != lim || lim != n) { 54 printf(" "); 55 } 56 } 57 for(int i = lim + 1; i <= n; ++ i) { 58 printf("0"); 59 if(i != n) printf(" "); 60 } 61 puts(""); 62 } 63 }

hdu6348: 序列計數