顯然,符合條件的數必須滿足任何長度的後綴字典序必須嚴格大於全串。
假設一個串 可以由幾個相同的串 拼接而成,我們稱 爲循環串。顯然所有循環串都是不滿足條件的。
那麼對於非循環串,那麼其所有循環表示(就是切下一個前綴拼在後面)都是互不相同的。給出一個結論:一個合法串和一個環的最小循環表示串一一對應。
先證明一個合法串一定是最小循環表示串。(以下 表示長度爲 的前綴, 表示長度爲 的後綴)假設合法串不是最小循環表示串,那麼設從第 位開始,即 是最小循環表示串,那麼我們可以得到 (矛盾)或者 並且 (也矛盾),於是得證。
再證明一個最小循環表示串一定是合法的。假設其不合法,那麼必然存在一個 (矛盾)或者 並且把 拼到後面能得到 (也矛盾),得證。
那麼我們設 表示長度爲 的合法串的個數,顯然有:
其中 是減去循環串, 是因爲 種循環表示中只有 種合法。我們設 ,問題要求的就是 ,那麼:
前一個和式是一個等比數列乘等差數列,用錯位相減直接求,後一個和式換成枚舉 ,得到
直接杜教篩即可。
代碼:
include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int mod=1000000007;
const int R=100000;
const int T=3000000;
ll n,i9,i2;
int mg[R+5],g[T+5];
ll ksm(ll a,ll b)
{
ll r=1;
for(;b;b>>=1,a=a*a%mod)
if(b&1) r=r*a%mod;
return r;
}
ll solve(ll x)
{
ll m=n/x,pp,ans;
if(m<T) return g[m];x=n/m;
if(x<R&&mg[x]>=0) return mg[x];
pp=ksm(10,m+1);
ans=(pp*(m-i9+mod)+i9+1)%mod*i9%mod;
for(ll l=2,r;l<=m;l=r+1)
{
r=m/(m/l);
ll s=((l+r)%mod)*((r-l+1)%mod)%mod*i2%mod;
ans=(ans-s*solve(x*l)%mod+mod)%mod;
}
if(x<R) mg[x]=ans;
return ans;
}
int main()
{
scanf("%lld",&n);
memset(mg,-1,sizeof(mg));
i9=ksm(9,mod-2);
i2=ksm(2,mod-2);
g[1]=10;
for(int i=2;i<=T;i++)
g[i]=10ll*g[i-1]%mod;
for(int i=1;i<=T;i++)
{
for(int j=(i<<1);j<=T;j+=i)
g[j]=(g[j]+mod-g[i])%mod;
g[i]=((ll)g[i]*i+g[i-1])%mod;
}
printf("%lld",solve(1));
return 0;
}