题意
问有多少个无限长度的数组要满足以下条件
1. 数组仅包含1, 2, 3, …, n
2. 如果n <= i, j,那么ai = aj
3. 如果i < j < k <= i + ai,那么aj = ak
答案对1e9 + 7 取模
1 <= n <= 10^6
分析
根据第二个条件可以得出这其实就是一个长度为n的数组。。。
接着分析一下第三个条件的性质:
如果a[i] > 1,且a[i+1] > 1,那么a[i+1…n]均等于a[i+1]。若a[i+1]=1,则a[i+1…i+a[i]]=1。
考虑dp,设f[i]表示一个长度为i的数组,且第i+1位可以任意放的方案。
分析一下不难发现f[i]=(∑i−1j=1f[j])−f[i−2]。也就是枚举i前面第一个k满足a[k] > 1的位置。
ans=f[n]+f[n−1]∗(n−1)+∑n−2i=0f[i]∗((n−1)∗(n−1)+i+1)
也就是枚举最后一个k满足a[k+1…n]都已经被确定。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=1000005;
const int MOD=1000000007;
int n,f[N],s[N];
int main()
{
scanf("%d",&n);
f[1]=f[2]=f[0]=s[0]=1;s[1]=2;s[2]=3;
for (int i=3;i<=n;i++)
{
f[i]=f[i-1]+s[i-3];
f[i]-=f[i]>=MOD?MOD:0;
s[i]=s[i-1]+f[i];
s[i]-=s[i]>=MOD?MOD:0;
}
int ans=f[n];
ans+=(LL)f[n-1]*(n-1)%MOD;
ans-=ans>=MOD?MOD:0;
for (int i=0;i<=n-2;i++) ans+=(LL)f[i]*((LL)(n-1)*(n-1)%MOD+i+1)%MOD,ans-=ans>=MOD?MOD:0;
printf("%d",ans);
return 0;
}