//给一串序列,找出长度大于2,且相邻两个数的差值不大于d的数子序列的个数
//dp[u] 表示以u为最后一个点满足条件的序列个数
//dp[u] = segma(dp[v] + 1) a[u] - a[v] <= d ;
//将用树状数组来找这个求和
//不过由于没有给a[i] , 所以需要对每个数编号,然后用二分找其对应的编号
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std ;
const int maxn = 100010 ;
const int mod = 9901 ;
const int inf = 1<<30 ;
int tree[maxn] ;
int a[maxn] ,len ,b[maxn];
void update(int x , int dx)
{
while(x < maxn)
{
tree[x] = (tree[x] + dx)%mod ;
x += x&(-x) ;
}
}
int getsum(int x)
{
int sum = 0 ;
while(x > 0)
{
sum = (sum + tree[x])%mod ;
x -= x&(-x) ;
}
return sum ;
}
int main()
{
//freopen("in.txt" ,"r" , stdin) ;
int n , d ;
while(~scanf("%d%d" , &n , &d))
{
memset(tree , 0 ,sizeof(tree)) ;
int ans = 0 ;
for(int i = 1;i <= n;i++)
scanf("%d" ,&a[i]) ,b[i] = a[i] ;
sort(a + 1 , a + 1 + n);
len = unique(a + 1 , a+1+n) - (a + 1);
for(int i = 1;i <= n;i++)
{
int pos_1 = upper_bound(a + 1 , a + 1 + len , b[i] + d) - (a + 1) ;
int pos_2 = lower_bound(a + 1 , a + 1 + len , b[i] - d) - (a + 1);
int pos = lower_bound(a + 1 , a + 1 + len , b[i]) - a;
int sum = ((getsum(pos_1) - getsum(pos_2))%mod + mod)%mod ;
ans = (ans + sum)%mod ;
update(pos , sum + 1) ;
}
printf("%d\n" , ans) ;
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
hdu3450Counting Sequences 树状数组
原文地址:http://blog.csdn.net/cq_pf/article/details/47168477