?
题意就不说了; hdu2227差不多只不过这道题不是递增 而是相邻差不超过d 其实是为都一样, 也有差别;
这道题没说范围 并且树之间的大小关系对结果有影响,所以树状数组里根据原来id来求,由于数值很大 所以还是用到离散化 这里的离散化感觉和映射差不多,离散化用来查找id;
当num【i】的id是x是,dp【i】表示方案数 很明显dp【i】=sun(dp【j】,j
?
#include
#include
#include
#include
using namespace std
; #define mod 9901
int num1
[100010
],num2
[100010
],mark
[100010
],tt
,n
; int coun
[100010
]; int update
(int a
,int b
) { for(int i
=a
;i
<=n
;i
+=(i
&-i
)) { coun
[i
]+=b
; coun
[i
]%=mod
; } return 0
; } int find
(int a
) { int s
=0
; for(int i
=a
;i
>=1
;i
-=(i
&-i
)) { s
+=coun
[i
]; s
%=mod
; } return s
; } int searchr
(int a
) { int left
=1
,right
=tt
,now
; while(left
<=right
) { int mid
=(left
+right
)/2
; if(mark
[mid
]<=a
) { now
=mid
; left
=mid
+1
; } else { right
=mid
-1
; } } return now
; } int searchl
(int a
) { int left
=1
,right
=tt
; while(left
<right
) { int mid
=(left
+right
)/2
; if(mark
[mid
]<a
) left
=mid
+1
; else if(mark
[mid
]==a
) return mid
; else right
=mid
; } return left
; } int main() { int i
,j
,d
; while(~scanf
("%d%d"
,&n
,&d
)) { for(i
=1
;i
<=n
;i
++) { scanf
("%d"
,&num1
[i
]); num2
[i
]=num1
[i
]; } sort
(num2
+1
,num2
+1
+n
); tt
=0
; num2
[0
]=-1
; for(i
=1
;i
<=n
;i
++) { if(num2
[i
]!=num2
[i
-1
]) { tt
++; mark
[tt
]=num2
[i
]; } } memset
(coun
,0
,sizeof(coun
)); int sum
=0
; int x
=searchl
(num1
[1
]); for(i
=1
;i
<=n
;i
++) { int left
=searchl
(num1
[i
]-d
)-1
; int right
=searchr
(num1
[i
]+d
); int now
=searchl
(num1
[i
]); int s
=find
(right
)-find
(left
); s
=(s
%mod
+mod
)%mod
; sum
+=s
; sum
%=mod
; update
(now
,s
+1
); } printf
("%d\n"
,sum
); } return 0
; }
?