[HNOI2011]数学作业
题目描述
小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题:
给定正整数
例如,
输入格式
一行两个正整数
输出格式
输出一行一个整数表示答案。
样例 #1
样例输入 #1
13 13
样例输出 #1
4
提示
【数据范围】
对于
对于
思路
观察这个
其中
设状态矩阵为
代码
#include<cstdio>
#include<iostream>
#define int long long
using namespace std;
int n,mod,num,r,k,kk;
struct matrix
{
int mat[4][4],n,m;
matrix(int a,int b)
{
n=a,m=b;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
mat[i][j]=0;
}
void set_i()
{
for(int i=1;i<=n;i++)
mat[i][i]=1;
}
matrix operator *(matrix b)
{
matrix ans(n,b.m);
for(int i=1;i<=n;i++)
for(int j=1;j<=b.m;j++)
for(int k=1;k<=m;k++)
ans.mat[i][j]=(ans.mat[i][j]+(mat[i][k]*b.mat[k][j])%mod)%mod;
return ans;
}
};
matrix qpow(matrix a,int b)
{
matrix ans(a.n,a.m);
ans.set_i();
while(b)
{
if(b&1)ans=ans*a;
a=a*a;
b>>=1;
}
return ans;
}
int numb(int x)
{
int ret=0;
while(x)
{
x/=10;
ret++;
}
return ret;
}
signed main()
{
scanf("%lld%lld",&n,&mod);
num=numb(n);
matrix f(1,3);
f.mat[1][1]=f.mat[1][2]=f.mat[1][3]=1;
matrix bb(3,3);
bb.mat[1][1]=10;bb.mat[2][1]=bb.mat[2][2]=bb.mat[3][1]=bb.mat[3][2]=bb.mat[3][3]=1;
matrix pro(3,3);
pro.set_i();
int mi=9,now=0;
for(int i=1;i<num;i++)
{
now+=mi;
if(i==1)pro=pro*qpow(bb,mi-1);
else pro=pro*qpow(bb,mi);
bb.mat[1][1]=(bb.mat[1][1]*10)%mod;
mi=(mi<<1)+(mi<<3);
}
if(num==1)pro=pro*qpow(bb,n-now-1);
else pro=pro*qpow(bb,n-now);
f=f*pro;
printf("%lld",f.mat[1][1]%mod);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】