考虑给定每个数字的个数,构造出这个序列:
肯定是1 2 1 2 3 2 3 2 3 4 3 4 ... 最大值,
或者1 2 1 2 3 2 3 2 3 4 3 4 ... 最大值 最大值-1。
本质不同的情况只有这两种,且互相不交。
设最大值为$m$,那么$1$到$m$都要有$1$个,剩下的数每多一个$i$,就要多一个$i+1$。
剩下的数假设有$t$个,那么对于每种情况,等价于$\lfloor\frac{t}{2}\rfloor$个相同的球放入$m$个不同的盒子里,允许空盒的方案数,即$C(\lfloor\frac{t}{2}\rfloor+m,m)$。
枚举最大值后累加贡献即可,注意特判最大值为$1$的情况。
时间复杂度$O(n+m)$。
#include<cstdio>
const int N=2000010,P=1000000007;
int n,m,i,f[N],r[N],ans;
inline int cal(int x,int y){
if(x<0)return 0;
x>>=1;
if(x==0)return 1;
return 1LL*f[x+y]*r[x]%P*r[y]%P;
}
int main(){
scanf("%d%d",&n,&m);
for(f[0]=f[1]=r[0]=r[1]=1,i=2;i<=n;i++){
f[i]=1LL*f[i-1]*i%P;
r[i]=-1LL*r[P%i]*(P/i)%P;
while(r[i]<0)r[i]+=P;
}
for(i=2;i<=n;i++)r[i]=1LL*r[i]*r[i-1]%P;
if(n&&m)ans=1;
for(i=2;i<=m;i++){
(ans+=cal(n-i,i-1))%=P;
(ans+=cal(n-i-1,i-1))%=P;
}
return printf("%d",ans),0;
}