hdu 2227 dp+树状数组优化

很容易可以想到状态转移方程:

  dp[i] = segma: dp[j] ( j < i && a[j] <= a[i] ), 其中dp[i]表示以a[i]结尾的不降子序列的个数。

但是n非常大,n^2的算法必然TLE,仔细想想其实式子右边是一个区间和的形式,即小于等于a[i]的a[j]的dp[j]的和,所以可以将a[i]离散化成t后将dp[i]的值存在t位置上,每次求解dp[i]就是查询一个前缀和,可以用树状数组来维护。

举个例子:对于1,50,13,34这四个数,离散化后变成了1,4,2,3。显然dp[1] = 1,所以我们在1位置插入1;而dp[2]就等于查询位置1到4(1+0+0+0)的和再加1,所以dp[2] = 2,我们在4位置插入2;dp[3]就等于(1+0)再加1,dp[3] = 2,我们在2位置插入2;dp[4]就等于(1+2+0)再加1为4,在位置3插入4,最后答案为整个数列的和:1+2+4+2=9.

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 using namespace std;
 6 
 7 typedef long long ll;
 8 const int N = 100001;
 9 const int MOD = 1000000007;
10 int c[N];
11 
12 struct Node 
13 {
14     ll s;
15     int id;    
16 } node[N];
17 
18 int lb( int i )
19 {
20     return i & -i;
21 }
22 
23 void set( int i, int x )
24 {
25     while ( i < N )
26     {
27         c[i] += x;
28         c[i] %= MOD;
29         i += lb(i);
30     }
31 }
32 
33 int get( int i )
34 {
35     int ans = 0;
36     while ( i > 0 )
37     {
38         ans += c[i];
39         ans %= MOD;
40         i -= lb(i);
41     }
42     return ans;
43 }
44 
45 bool cmp1( Node n1, Node n2 )
46 {
47     if ( n1.s != n2.s ) return n1.s < n2.s;
48     return n1.id < n2.id;
49 }
50 
51 bool cmp2( Node n1, Node n2 )
52 {
53     return n1.id < n2.id;    
54 }
55 
56 int main ()
57 {
58     int n;
59     while ( scanf("%d", &n) != EOF )
60     {
61         for ( int i = 1; i <= n; i++ )
62         {
63             scanf("%I64d", &node[i].s);
64             node[i].id = i;            
65         }
66         sort( node + 1, node + 1 + n, cmp1 );
67         for ( int i = 1; i <= n; i++ )
68         {
69             node[i].s = i;
70         }
71         sort( node + 1, node + 1 + n, cmp2 );
72         memset( c, 0, sizeof(c) );
73         for ( int i = 1; i <= n; i++ )
74         {
75             int pn = node[i].s;
76             int nn = get(pn) + 1;
77             set( pn, nn );
78         }
79         printf("%d
", get(n));
80     }
81     return 0;
82 }
原文地址:https://www.cnblogs.com/huoxiayu/p/4688282.html