分析:
很容易想到DP,设 D P [ i ] [ 0 / 1 ] DP[i][0/1] DP[i][0/1]表示已经处理了前i个,末尾一个属于A集合/B集合。
那么
D
P
[
i
]
[
0
]
=
∑
D
P
[
k
]
[
1
]
DP[i][0]=\sum DP[k][1]
DP[i][0]=∑DP[k][1],其中
K
K
K满足以下条件:
1、
K
<
i
K<i
K<i
2、
∀
j
∈
[
K
+
2
,
i
]
,
a
j
−
a
j
−
1
≥
A
(
B
)
\forall j\in[K+2,i],a_j-a_{j-1}\geq A(B)
∀j∈[K+2,i],aj−aj−1≥A(B)
3、
a
i
+
1
−
a
k
≥
B
(
A
)
a_{i+1}-a_k\geq B(A)
ai+1−ak≥B(A)
然后用前缀和优化水过去就行了。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define SF scanf
#define PF printf
#define MAXN 100010
#define MOD 1000000007
using namespace std;
typedef long long ll;
ll a[MAXN],A,B;
int n,lasA1[MAXN],lasB1[MAXN];
ll dp[MAXN][2],sum0[MAXN],sum1[MAXN];
int find(ll val){
int l=1,r=n,res=0;
while(l<=r){
int mid=(l+r)>>1;
if(a[mid]<=val){
res=mid;
l=mid+1;
}
else
r=mid-1;
}
return res;
}
int main(){
//freopen("division.in","r",stdin);
//freopen("division.out","w",stdout);
SF("%d%lld%lld",&n,&A,&B);
for(int i=1;i<=n;i++)
SF("%lld",&a[i]);
for(int i=1;i<=n;i++){
lasA1[i]=lasA1[i-1];
lasB1[i]=lasB1[i-1];
if(a[i]-a[i-1]<A||i==1)
lasA1[i]=i;
if(a[i]-a[i-1]<B||i==1)
lasB1[i]=i;
}
sum0[0]=sum1[0]=1;
for(int i=1;i<=n;i++){
sum0[i]=sum0[i-1];
sum1[i]=sum1[i-1];
int i1=lasA1[i]-1;
int i2=find(a[i+1]-B);
if(i==n)
i2=n;
if(i1<=i2){
if(i1==0)
dp[i][0]=sum1[i2];
else
dp[i][0]=(sum1[i2]-sum1[i1-1]+MOD)%MOD;
}
// PF("<%d %d>\n",i1,i2);
i1=lasB1[i]-1;
i2=find(a[i+1]-A);
if(i==n)
i2=n;
if(i1<=i2){
if(i1==0)
dp[i][1]=sum0[i2];
else
dp[i][1]=(sum0[i2]-sum0[i1-1]+MOD)%MOD;
}
//PF("[%d %d]\n",i1,i2);
/*if(dp[i][0]!=0){
PF("{%lld %lld}\n",dp[i][0],dp[i][1]);
PF("--------\n");
}*/
sum0[i]=(sum0[i-1]+dp[i][0])%MOD;
sum1[i]=(sum1[i-1]+dp[i][1])%MOD;
}
PF("%lld",(dp[n][0]+dp[n][1])%MOD);
}