HDU 2836 Traversal 简单DP + 树状数组

题意:给你一个序列,问相邻两数高度差绝对值小于等于H的子序列有多少个。

dp[i]表示以i为结尾的子序列有多少,易知状态转移方程为:dp[i] = sum( dp[j] ) + 1;( abs( height[i] - height[j] ) <= H )

由abs( height[i] - height[j] ) <= H 可得 height[i] - H <= height[j] <= height[i] + H

将序列中的数离散化,每个height对应一个id, 用树状数组求区间[ height[i] - H的id, height[i] + H的id ]内dp[j]的和,并且每次把新得到的dp[i]更新到树状数组中height[i]的id对应的位置。

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 
 8 const int MAXN = 100100;
 9 const int MOD = 9901;
10 
11 int dp[MAXN];
12 int height[MAXN];
13 int num[MAXN];
14 int C[MAXN];
15 int n, d;
16 
17 int lowbit( int x )
18 {
19     return x & ( -x );
20 }
21 
22 int Query( int x )
23 {
24     int res = 0;
25     while ( x > 0 )
26     {
27         res += C[x];
28         res %= MOD;
29         x -= lowbit(x);
30     }
31     return res;
32 }
33 
34 void Add( int x, int v )
35 {
36     while ( x <= n )
37     {
38         C[x] += v;
39         C[x] %= MOD;
40         x += lowbit(x);
41     }
42     return;
43 }
44 
45 int main()
46 {
47     while ( ~scanf( "%d%d", &n, &d ) )
48     {
49         for ( int i = 1; i <= n; ++i )
50         {
51             scanf( "%d", &height[i] );
52             num[i] = height[i];
53         }
54 
55         sort( num + 1, num + n + 1 );
56         int cnt = unique( num + 1, num + n + 1 ) - num - 1;
57 
58         memset( C, 0, sizeof(C) );
59         int ans = 0;
60         dp[0] = 0;
61         for ( int i = 1; i <= n; ++i )
62         {
63             int id = lower_bound( num + 1, num + cnt + 1, height[i] ) - num;
64             int left = lower_bound( num + 1, num + cnt + 1, height[i] - d ) - num;
65             int right = upper_bound( num + 1, num + cnt + 1, height[i] + d ) - num - 1;
66             dp[i] = ( Query( right ) - Query( left - 1 ) + 1 ) % MOD;
67             ans += dp[i];
68             Add( id, dp[i] );
69         }
70 
71         if ( ans >= n ) ans -= n;
72         else ans = 0;
73         printf("%d\n", ans % MOD );
74     }
75     return 0;
76 }

 

posted @ 2013-07-18 12:36  冰鸮  阅读(303)  评论(0编辑  收藏  举报