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]本身成串。*/

原创粉丝点击