hdu2836(2009多校第三场) 相邻项绝对值小于等于k的序列数(线段树+sort unique lowerbound)
和codeforces上次那个题目差不多吧,都是用线段树求和加速dp
为了下次好找,把几个stl放标题哈哈哈
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 #define MOD 9901 6 int sumv[400005],a[100005],b[100005]; 7 int query(int o,int l,int r,int ql,int qr) 8 { 9 int mid=l+(r-l)/2,ans=0; 10 if (ql<=l&&qr>=r) return sumv[o]; 11 if (ql<=mid) ans+=query(o*2,l,mid,ql,qr); 12 if (qr>mid) ans+=query(o*2+1,mid+1,r,ql,qr); 13 return ans%MOD; 14 } 15 void update(int o,int l,int r,int p,int v) 16 { 17 int mid=l+(r-l)/2; 18 if (l==r) sumv[o]=(sumv[o]+v)%MOD; 19 else{ 20 if (p<=mid) update(o*2,l,mid,p,v); 21 if (p>mid) update(o*2+1,mid+1,r,p,v); 22 sumv[o]=(sumv[o*2]+sumv[o*2+1])%MOD; 23 } 24 return; 25 } 26 int main() 27 { 28 int n,k,i,cnt,t1,t2,tmp,ans; 29 while (~scanf("%d%d",&n,&k)) 30 { 31 for (i=1;i<=n;i++) 32 { 33 scanf("%d",&a[i]); 34 b[i]=a[i]; 35 } 36 sort(b+1,b+n+1); 37 cnt=unique(b+1,b+n+1)-b-1; 38 memset(sumv,0,sizeof(sumv)); 39 ans=0; 40 for (i=1;i<=n;i++) 41 { 42 t1=lower_bound(b+1,b+cnt+1,a[i]-k)-b; 43 t2=upper_bound(b+1,b+cnt+1,a[i]+k)-b-1; 44 tmp=query(1,1,cnt,t1,t2); 45 ans=(ans+tmp)%MOD; 46 t1=lower_bound(b+1,b+cnt+1,a[i])-b; 47 update(1,1,cnt,t1,tmp+1); 48 } 49 printf("%d\n",ans); 50 } 51 return 0; 52 }