本题一看就不会,但怎么看都像有规律的样子,所以我们考虑打表,但看表看了半天我都没看出规律,所以最后只交了一个暴力
本题可以找出规律,以15个为周期,有重复的部分
123432,234321,343212,432123,321234,123432,432123,212343,432123,123432,321234,432123,343212,234321,123432
最后的数也有规律
1,2,3,4,32,123,43,2123,432,1234,32123,43212,34321,23432,123432
对于重复的部分,数列求和就行了
对于不重复的部分,直接加上
注意点
- 本题模数不是质数,所以不能用费马小定理,所以只能用拓展欧几里得或线性筛,我只直接扫出来的
- 对第一个15要单独计算
- 后面的是一个经典的求和模型
t p p [ 1 ] ∗ ( 10 ∗ n + 1 0 7 ∗ ( n − 1 ) + . . . + 1 0 6 ∗ n − 5 ) tpp[1]*(10*n+10^7*(n-1)+...+10^{6*n-5}) tpp[1]∗(10∗n+107∗(n−1)+...+106∗n−5)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,mod=123454321;
int tpp[15]={123432,234321,343212,432123,321234,123432,432123,212343,432123,123432,321234,432123,343212,234321,123432};
int tpp2[15]={1,2,3,4,32,123,43,2123,432,1234,32123,43212,34321,23432,123432};
int sum[15]={1,1,1,1,2,3,2,4,3,4,5,5,5,5,6};
int now[15];
ll ksm(ll x,ll pow){
ll ans=1,res=x%mod;
while(pow){
if(pow&1) ans=1ll*ans*res%mod;
res=1ll*res*res%mod;
pow>>=1;
}
return ans;
}
int ny=96007682;
int main(){
scanf("%lld",&n);
ll anss=0,tp=n/15,k=n%15;
if(tp==0){for(int i=0;i<k;i++)anss=(1ll*tpp2[i]+anss)%mod;printf("%lld",anss);exit(0);}
for(int i=0;i<15;i++){anss=(1ll*tpp2[i]*tp+anss)%mod;}
ll ans6=0;
tp--;
if(tp==0){
ll ans2=0;
for(int i=0;i<k;i++){
ll stmp=ksm(10,sum[i]);
anss=(1ll*tpp[i]*stmp%mod+anss)%mod;
ans2=(ans2+tpp2[i])%mod;
}
printf("%lld",(anss+ans2)%mod);
exit(0);
}
for(int i=0;i<15;i++){
ll ans3=ksm(10,6*tp+sum[i]+6);
ll ans4=ksm(10,sum[i]+6);
ll ans2=((1ll*ny*(ans3-ans4+1ll*mod)%mod*(1ll*tpp[i]))%mod);
ll ans5=1ll*tp*ksm(10,sum[i])%mod*(1ll*tpp[i])%mod;
ans6=((ans2-ans5+mod)%mod*(1ll*ny)%mod+ans6)%mod;
}
ll ansss=(anss+ans6)%mod,sum0=0,sum1=0;
for(int i=0;i<k;i++){
ll tp11=ksm(10,1ll*sum[i]+6*tp+6);
ll tp22=ksm(10,sum[i]);
ll tmp33=(tp11-tp22+1ll*mod)%mod*(1ll*ny)%mod;
sum0=(sum0+1ll*tpp[i]*tmp33%mod)%mod;
sum1=(sum1+tpp2[i])%mod;
}
printf("%lld",((ansss+sum0)%mod+sum1)%mod);
}