http://acm.hdu.edu.cn/showproblem.php?pid=3450
#include<iostream>
#include<algorithm>
using namespace std;
#define mod 9901
#define N 100005
int a[N],b[N],real[N],c[N];
int n,d,ind;
int lowbit(int x){
return x&(-x);
}
void update(int x,int k){
while(x<=n){
c[x]+=k;
x+=lowbit(x);
}
}
int getsum(int x){
int ret=0;
while(x>0){
ret+=c[x];
x-=lowbit(x);
if(ret>=mod)
ret%=mod;
}
return ret;
}
int find(int x){
int f=1,l=ind-1;
while(f<=l){
int mid=(f+l)>>1;
if(real[mid]==x)
return mid;
if(real[mid]>x)
l=mid-1;
else
f=mid+1;
}
}
int find_u(int x){
int f=1,l=ind-1;
while(f<=l){
int mid=(f+l)>>1;
if(real[mid]<=x)
f=mid+1;
else
l=mid-1;
}
return l;
}
int find_d(int x){
int f=1,l=ind-1;
while(f<=l){
int mid=(f+l)>>1;
if(real[mid]>=x)
l=mid-1;
else
f=mid+1;
}
return f;
}
int main(void){
while(~scanf("%d%d",&n,&d)){
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b,b+n);
real[1]=b[0];
ind=2;
for(int i=1;i<n;i++)
if(b[i]!=b[i-1])
real[ind++]=b[i];
memset(c,0,sizeof(c));
int ans=0;
for(int i=0;i<n;i++){
int k=find(a[i]);
int up=find_u(a[i]+d);
int dn=find_d(a[i]-d);
int temp=getsum(up)-getsum(dn-1)+1;
if(temp<0)
temp+=mod;
ans+=temp;
if(ans>=mod)
ans%=mod;
update(k,temp);
}
if(ans>=n)
printf("%d\n",ans-n);
else
printf("%d\n",((ans-n)%mod+mod)%mod);
}
}
注意查找上下界的时候右端点要从ind-1开始,而不是随便用ind代替