hdu 3450 Counting Sequences 树状数组
来源:互联网 发布:淘宝卖家信誉怎么清零 编辑:程序博客网 时间:2024/05/16 06:18
#include <cstdio>#include <cstring>#include <cmath>#include <iostream>#include <algorithm>using namespace std;#define lowbit(x) ((-x)&x)#define INF 1000000000const 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]本身成串。*/