题目大意
一个字符集为0~9的长度为n的数字串,f(n)为其本身的字典序在所有后缀中是严格最小的字符串的数量。
求
∑ni=1f(i)∗i2
结论
我们发现一个有周期的串的本身不可能是严格最小后缀。
对于没有周期的串,当做循环串来看,可以转出n个不同的字符串,一定只有一个能被算入f(n)。
可以知道f(n)是没有周期的串个数除以n。
f(n)=∑d|nμ(d)∗10nd
推式子
ans=∑ni=1i∗∑d|iμ(d)∗10id
ans=∑nd=1d∗μ(d)∗∑⌊nd⌋i=1i∗10i
可以分块杜教筛解决。
#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int maxn=10000000+10,mo=1000000007,inv2=(mo+1)/2,inv9=(mo+1)/9;
int mu[maxn]/*,sum[maxn]*/,pri[maxn],gg[10000+10];
bool bz[maxn];
ll i,j,k,l,r,t,m,top,ans;
ll n,N;
int qsm(int x,int y){
if (!y) return 1;
int t=qsm(x,y/2);
t=(ll)t*t%mo;
if (y%2) t=(ll)t*x%mo;
return t;
}
void prepare(){
mu[1]=1;
fo(i,2,maxn-10){
if (!bz[i]){
mu[i]=-1;
pri[++top]=i;
}
fo(j,1,top){
if ((ll)i*pri[j]>maxn-10) break;
bz[i*pri[j]]=1;
if (i%pri[j]==0) break;
mu[i*pri[j]]=-mu[i];
}
}
fo(i,1,maxn-10){
mu[i]=i*mu[i];
(mu[i]+=mu[i-1])%=mo;
}
}
int getsum(ll n){
int t=(ll)qsm(10,(n+1)%(mo-1))*(n%mo)%mo;
int r=(ll)((ll)qsm(10,(n+1)%(mo-1))-10)*inv9%mo;
(t-=r)%=mo;
return (ll)t*inv9%mo;
}
int S(ll n){
n=n%mo;
return (ll)n*(n+1)%mo*inv2%mo;
}
int getmu(ll n){
if (n<=maxn-10) return mu[n];
int k=N/n;
if (gg[k]) return gg[k];
ll i,j,l,r;
int t=1;
i=2;l=S(1);
while (i<=n){
j=n/(n/i);
r=S(j);
(t-=(ll)(r-l)*getmu(n/i)%mo)%=mo;
l=r;
i=j+1;
}
return gg[k]=t;
}
int main(){
freopen("psy.in","r",stdin);freopen("psy.out","w",stdout);
prepare();
scanf("%lld",&n);
N=n;
i=1;l=0;
while (i<=n){
j=n/(n/i);
r=getmu(j);
(ans+=(ll)(r-l)*getsum(n/i)%mo)%=mo;
l=r;
i=j+1;
}
(ans+=mo)%=mo;
printf("%d\n",ans);
}