AT_abc129_f [ABC129F] Takahashi's Basics in Education and Learning 题解

题目传送门

前置知识

矩阵加速递推

解法

\(f_{i}\) 表示将 \(s_{1} \sim s_{i}\) 拼起来后的值,状态转移方程形如 \(f_{i}=10^{k}f_{i-1}+s_{i}\) ,其中 \(k=\left\lfloor \log_{10}s_{i} \right\rfloor+1\)

又因为保证等差数列中的元素 \(\le 10^{18}\) ,对于每个 \(k \in [1,19]\) 分别进行矩阵加速递推即可。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define sort stable_sort 
#define endl '\n'
ll p;
struct Matrix
{
	ll ma[4][4];
	Matrix()
	{
		memset(ma,0,sizeof(ma));
	}
	Matrix operator * (const Matrix another)
	{
		Matrix ans;
		for(ll i=1;i<=3;i++)
		{
			for(ll j=1;j<=3;j++)
			{
				for(ll h=1;h<=3;h++)
				{
					ans.ma[i][j]=(ans.ma[i][j]+(ma[i][h]%p)*(another.ma[h][j]%p)%p)%p;
				}
			}
		}
		return ans;
	}
}f,Base;
Matrix qpow(Matrix a,ll b)
{
	Matrix ans;
	for(ll i=1;i<=3;i++)
	{
		ans.ma[i][i]=1;
	}
	while(b)
	{
		if(b&1)
		{
			ans=ans*a;
		}
		b>>=1;
		a=a*a;
	}
	return ans;
}
int main()
{
// #define Isaac
#ifdef Isaac
	freopen("in.in","r",stdin);
	freopen("out.out","w",stdout);
#endif
	ll a,b,n,cnt;
	cin>>n>>a>>b>>p;
	f.ma[1][1]=0;
	f.ma[1][2]=a;
	f.ma[1][3]=1;
	for(ull i=10;i<=1000000000000000000;i*=10)
	{
		if(a<=i)
		{
			cnt=min(n,(ll)ceil(1.0*(i-a)/b));//计算迭代次数
			n-=cnt;
			a+=cnt*b;
			if(cnt>=1)
			{
				Base.ma[1][1]=i%p;
				Base.ma[1][2]=0;
				Base.ma[1][3]=0;
				Base.ma[2][1]=1;
				Base.ma[2][2]=1;
				Base.ma[2][3]=0;
				Base.ma[3][1]=0;
				Base.ma[3][2]=b%p;
				Base.ma[3][3]=1;
				f=f*qpow(Base,cnt);
			}
		}
	}
	printf("%lld\n",f.ma[1][1]);
	return 0;
}
posted @ 2024-12-18 15:54  hzoi_Shadow  阅读(16)  评论(0编辑  收藏  举报
扩大
缩小