[ARC071F] Infinite Sequence
に言及
各数1~nの無限長のシーケンスを構築し、以下を満たすようにします.のn番目の数は、その後の数と同じ です.は、各数xについて、後のxの数と同じである.
何種類の案があるか聞いてください.
問題解
dpを考慮して、f[i]f[i]f[i]f[i]がi~n番目のビットを表すシナリオ数とし、dpを逆さにする.
転送は3つのケースに分けられます.
i位が1の場合、f[i]+=f[i+1]f[i]+=f[i+1]f[i]+=f[i+1]となる.
このシーケンスは、i番目が1である、i+1番目が1でない場合には、x y y y y y y y y y y y y y y y y y y y y yにしか成長する.xyyyyyyyyyyyy... xyyyyyyyyyyyy...のように、x x xとy y yは任意の非1数を埋めることができるので、f[i]+=(n-1)∗(n-1)f[i]+=(n-1)*(n-1)f[i]+=(n-1)∗(n-1)である.
i番目のビットが1ではないがi+1番目のビットが1である場合、このシーケンスはx 11111 S x 1111 S x 1111 Sのように成長するので、x x x毎にf[i]+=f[i+x+1]f[i]+=f[i+x+1]f[i]+=f[i+x+1]f[i]+=f[i+x+1]f[i+x+1>n i+x+1>nである場合、f[i+x+1]=1 f[i+x+1]=1 f[i+x+1]=1f fの接尾辞の和を1つ維持すればO(1)O(1)O(1)遷移が可能になる.
時間複雑度:O(n)O(n)O(n)O(n).
コード:
各数1~nの無限長のシーケンスを構築し、以下を満たすようにします.
何種類の案があるか聞いてください.
問題解
dpを考慮して、f[i]f[i]f[i]f[i]がi~n番目のビットを表すシナリオ数とし、dpを逆さにする.
転送は3つのケースに分けられます.
i位が1の場合、f[i]+=f[i+1]f[i]+=f[i+1]f[i]+=f[i+1]となる.
このシーケンスは、i番目が1である、i+1番目が1でない場合には、x y y y y y y y y y y y y y y y y y y y y yにしか成長する.xyyyyyyyyyyyy... xyyyyyyyyyyyy...のように、x x xとy y yは任意の非1数を埋めることができるので、f[i]+=(n-1)∗(n-1)f[i]+=(n-1)*(n-1)f[i]+=(n-1)∗(n-1)である.
i番目のビットが1ではないがi+1番目のビットが1である場合、このシーケンスはx 11111 S x 1111 S x 1111 Sのように成長するので、x x x毎にf[i]+=f[i+x+1]f[i]+=f[i+x+1]f[i]+=f[i+x+1]f[i]+=f[i+x+1]f[i+x+1>n i+x+1>nである場合、f[i+x+1]=1 f[i+x+1]=1 f[i+x+1]=1f fの接尾辞の和を1つ維持すればO(1)O(1)O(1)遷移が可能になる.
時間複雑度:O(n)O(n)O(n)O(n).
コード:
#include
using namespace std;
#define MAXN 1000010
#define mod 1000000007
int n,f[MAXN],add;
int main()
{
scanf("%d",&n);
f[n]=n;
f[n-1]=(long long)n*n%mod;
for(int i=n-2;i>=1;--i)
{
add=(add+f[i+3])%mod;
f[i]=f[i+1];
f[i]=(f[i]+(long long)(n-1)*(n-1)%mod)%mod;
f[i]=(f[i]+add)%mod;
f[i]=(f[i]+i+1)%mod;
}
printf("%d
",f[1]);
}