[ARC020C] A mod B Problem 解题记录
看到题解区没有用矩乘写的,所以我来水一发。
题意简述
现在有一个很大的整数,由
N
N
N 个部分组成,第
i
i
i 个部分由
a
i
a_i
ai 重复
l
i
l_i
li 次得到。
求大整数模
B
B
B 的值。
题目分析
如果不考虑取模的话,那么这个数字
a
n
s
ans
ans 可以写为
a
1
a
1
⋯
a
1
⏟
l
1
个
a
2
a
2
⋯
a
2
⏟
l
2
个
a
3
a
3
⋯
a
3
⏟
l
3
个
⋯
a
n
a
n
⋯
a
n
⏟
l
n
个
‾
\overline{\underbrace{a_1 a_1 \cdots a_1} _{l_1个}\underbrace{a_2 a_2 \cdots a_2} _{l_2个}\underbrace{a_3 a_3 \cdots a_3} _{l_3个} \cdots \underbrace{a_n a_n \cdots a_n} _{l_n个}}
l1个
a1a1⋯a1l2个
a2a2⋯a2l3个
a3a3⋯a3⋯ln个
anan⋯an
如果从
1
1
1 开始遍历,对于每个
i
i
i,
a
n
s
ans
ans 就会乘上
a
i
a_i
ai 的位数再加上
a
i
a_i
ai,重复
l
i
l_i
li 次。
形式化的来讲,
a
n
s
→
a
n
s
×
1
0
log
a
i
+
1
+
a
i
ans \to ans \times 10^{\log a_i + 1} + a_i
ans→ans×10logai+1+ai,重复
l
i
l_i
li 次。
对于这种转移柿子,我们可以自然而然地想到矩乘。
考虑初始矩阵。需要记录
a
n
s
ans
ans,并且每次要加上
a
i
a_i
ai,所以可以设初始矩阵为
[
a
n
s
a
i
]
\begin{bmatrix} ans & a_i \end{bmatrix}
[ansai]
每次
a
n
s
ans
ans 变为
a
n
s
×
1
0
(
log
a
i
+
1
)
+
a
i
ans \times 10^{(\log a_i + 1)} + a_i
ans×10(logai+1)+ai,重复
l
i
l_i
li 次,所以需要转移矩阵为
[
1
0
log
a
i
+
1
0
1
1
]
l
i
\begin{bmatrix} 10^{\log a_i+1}& 0\\ 1&1 \end{bmatrix}^{l_i}
[10logai+1101]li
遍历
1
∼
n
1 \sim n
1∼n,每次乘上转移矩阵,最终值为初始矩阵的
a
n
s
ans
ans。
注意:本题为早期 Atcoder 结尾需要输出换行。
AC Code
#include<bits/stdc++.h>
#define arrout(a,n) rep(i,1,n)std::cout<<a[i]<<" "
#define arrin(a,n) rep(i,1,n)std::read()
#define rep(i,x,n) for(int i=x;i<=n;i++)
#define dep(i,x,n) for(int i=x;i>=n;i--)
#define erg(i,x) for(int i=head[x];i;i=e[i].nex)
#define dbg(x) std::cout<<#x<<":"<<x<<" "
#define mem(a,x) memset(a,x,sizeof a)
#define all(x) x.begin(),x.end()
#define arrall(a,n) a+1,a+1+n
#define PII std::pair<int,int>
#define m_p std::make_pair
#define u_b upper_bound
#define l_b lower_bound
#define p_b push_back
#define CD const double
#define CI const int
#define int long long
#define il inline
#define ss second
#define ff first
#define itn int
int read() {
char ch=getchar();
int r=0,w=1;
while(ch<'0'||ch>'9') w=ch=='-'?-1:w,ch=getchar();
while(ch>='0'&&ch<='9') r=r*10+ch-'0',ch=getchar();
return r*w;
}
CI N=1e4+5;
int n,a[N],l[N],mod;
struct matrix {
int mat[2][2];
matrix() {
mem(mat,0);
}
matrix operator*(const matrix& b)const {
matrix ans;
rep(i,0,1) {
rep(j,0,1) {
rep(k,0,1) {
ans.mat[i][j]=(ans.mat[i][j]+mat[i][k]*b.mat[k][j]%mod)%mod;
}
}
}
return ans;
}
matrix operator^(int& b)const {
matrix ans,a=*this;
ans.mat[0][0]=ans.mat[1][1]=1;
while(b) {
if(b&1) {
ans=ans*a;
}
a=a*a;
b>>=1;
}
return ans;
}
}g,t;
int32_t main() {
n=read();
rep(i,1,n) {
a[i]=read();
l[i]=read();
}
mod=read();
rep(i,1,n) {
g.mat[0][1]=a[i];
t.mat[0][0]=(int)pow(10,(int)log10(a[i])+1)%mod;
t.mat[1][0]=1;
t.mat[1][1]=1;
g=g*(t^l[i]);
}
std::cout<<g.mat[0][0]%mod<<"\n";
return 0;
}