题解:AT_abc129_f [ABC129F] Takahashi's Basics in Education and Learning
Imerance1018 · · 题解
默认数列下标从
用 int128 AC 后才发现保证等差数列中的数小于
Description
给定一个长度为
Solution
考虑矩阵快速幂,由于转移矩阵由当前项的位数决定,需要进行分段。
将十进制下位数相同的数字放在一起考虑,易得位数为
将数列分成
Code
#include<bits/stdc++.h>
#define int long long
#define ll __int128
using namespace std;
int l;
ll a,b;
int mod;
struct matrix
{
int val[4][4];
matrix(){memset(val,0,sizeof(val));}
matrix operator *(const matrix &x)const
{
matrix res;
for(int i=1;i<=3;i++)
for(int k=1;k<=3;k++)
for(int j=1;j<=3;j++)
res.val[i][j]=(res.val[i][j]+val[i][k]*x.val[k][j]%mod)%mod;
return res;
}
}G,base;
int getlen(ll x)
{
int tot=0;
while(x!=0)
{
tot++;
x/=10;
}
return tot;
}
ll read()
{
char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
ll x=0;
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x;
}
void print(ll x)
{
if(x>9)print(x/10);
cout<<(int)(x%10);
}
signed main()
{
cin>>l;
a=read();
b=read();
cin>>mod;
ll tmp=1;
for(int i=1;i<getlen(a);i++)tmp*=10;
base.val[1][1]=base.val[1][2]=a%mod,base.val[1][3]=b%mod;
for(int i=getlen(a);i<=getlen(a+(l-1)*b);i++)
{
int L=(max(tmp,a+b)-a+b-1)/b+1,R=(min(tmp*10-1,a+(l-1)*b)-a)/b+1;
G.val[1][1]=tmp*10%mod,G.val[2][1]=G.val[2][2]=G.val[3][1]=G.val[3][2]=G.val[3][3]=1;
int x=R-L+1;
while(x)
{
if(x&1)base=base*G;
G=G*G;
x>>=1;
}
tmp*=10;
}
cout<<base.val[1][1]<<"\n";
return 0;
}