#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
#define lowbit(x) ((-x)&x)
#define INF 1000000000
const int maxn=100005;
const int mod=9901;
int a[maxn],b[maxn],c[maxn],f[maxn];
void add(int x,int val)//树状数组添加
{
while(x<maxn)
{
c[x]=(c[x]+val)%mod;
x+=lowbit(x);
}
}
int sum(int x)//求和
{
int s=0;
while(x>0)
{
s=(c[x]+s)%mod;
x-=lowbit(x);
}
return s;
}
int main()
{
int n,d;
while(scanf("%d%d",&n,&d)!=EOF)
{
int i,j,k,t=1;
memset(c,0,sizeof(c));
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b,b+n);
f[0]=b[0];
for(i=1;i<n;i++)
if(b[i]!=b[i-1])
f[t++]=b[i];
f[t++]=INF;
int x,y,z,val,ans;
for(i=0;i<n;i++)
{
x=lower_bound(f,f+t,a[i])-f+1;
y=upper_bound(f,f+t,a[i]+d)-f;
z=lower_bound(f,f+t,a[i]-d)-f+1;
val=sum(y)-sum(z-1)+1;//在z~y范围内的都符合要求
val=(val%mod+mod)%mod;
add(x,val);
}
ans=sum(t);
ans=((ans-n)%mod+mod)%mod;//需要减去单个的还有避免答案为负
printf("%d\n",ans);
}
return 0;
}
/*
树状数组
对于每项a[i],则以[a[i]-d,a[i]+d]范围内的数结尾的子串,加上a[i],就可以成为符合要求的另一个子串,用树状数组维护,最后需要删去单个元素的子串。
树状数组sum(x)记录的是以1~x结尾的符合要求的子串个数,则sum(y)-sum(z-1)+1,就是[z,y]范围子串加上a[i]后新增子串,还要加上a[i]本身成串。
*/
hdu 3450 Counting Sequences 树状数组
最新推荐文章于 2021-10-22 22:57:49 发布