4 1
0 0 1 1
5
显然用DP
设 f[i]表示第 1~i 个数分段的方案数。
转移固然是符合要求就转。
可以用数据结构维护,我用了线段树
#include
#include
#include
using namespace std;
const int maxn=1e5+77,mod=1e9+7;
int n,k,s[maxn],a[maxn*8],ss=0,f[maxn];
void ins(int v,int l,int r,int p,int val)
{
if(l==r)
{
a[v]=(a[v]+val)%mod; return;
}
int mid=(l+r)>>1;
if(p<=mid) ins(v*2,l,mid,p,val); else ins(v*2+1,mid+1,r,p,val);
a[v]=(a[v*2]+a[v*2+1])%mod;
}
void query(int v,int l,int r,int ll,int rr)
{
if(l==ll&&r==rr)
{
ss=(ss+a[v])%mod; return;
}
int mid=(l+r)>>1;
if(rr<=mid) query(v*2,l,mid,ll,rr);else if(ll>mid) query(v*2+1,mid+1,r,ll,rr); else
{
query(v*2,l,mid,ll,mid); query(v*2+1,mid+1,r,mid+1,rr);
}
}
int main()
{
scanf("%d%d",&n,&k);
int x;
for(int i=1; i<=n; i++) scanf("%d",&x),s[i]=s[i-1]+(x?1:-1);
ins(1,0,2*n,n,1);
for(int i=1; i<=n; i++)
{
x=s[i]+n;
ss=0; query(1,0,2*n,max(0,x-k),min(x+k,2*n));
f[i]=ss; ins(1,0,2*n,x,ss);
}
printf("%d",f[n]);
}