AtCoder Beginner Contest 293 E - Geometric Progression 无法求逆元/数列通项
创始人
2024-06-02 03:42:42
0

传送门:ATcoder

题目描述:

Given integers A, X, and M,find ∑i=0X−1Ai\sum\limits_{i=0}^{X-1}Aii=0∑X−1​Ai,modulo M

输入:
1000000000 1000000000000 998244353
输出:
919667211

首先X的范围达到了1e121e121e12,所以O(X)O(X)O(X)的算法肯定是过不了的.

然后当时我赛时就想起来之前有一次我做过一道自幂的题目,然后对与一个数不断自幂取模来说,必存在一个循环节.这个我在上述链接中已经有详细证明+解释,此处就不在赘述了.然后我就基于循环节的想法去打这道题.复杂度应该是低于O(M)O(M)O(M)的.但是可能是因为取模运算比较慢,所以最后是TLE了.

然后现在讲一下正解.首先假设你没有像我一样sb的去用循环节去做这道题,那么你应该不难发现AiA^iAi是一个等比数列,那么原题就是一道等比数列求和的题目,那么你可能十分的激动直接开做,1−qX1−X\frac{1-q^X}{1-X}1−X1−qX​,分子只用快速幂可以解决,但是你会发现分母需要使用逆元,但是这个逆元可能是不存在的(可以证明,但是比较麻烦).所以不能直接求.

我们可以换一种想法就是将∑i=0X−1Ai\sum\limits_{i=0}^{X-1}Aii=0∑X−1​Ai看成是一个等比数列的一个通项,也就是设一个Ci=∑i=0X−1AiCi=\sum\limits_{i=0}^{X-1}AiCi=i=0∑X−1​Ai,可以显然的发现CiCiCi本身就是一个等比数列,所以我们现在的任务就是求出CX的值即可.我们可以发现Ci=C(i−1)∗A+1Ci=C(i-1)*A+1Ci=C(i−1)∗A+1对于这种数列题,可以使用矩阵来快速解决

考虑有
[Ci]=[A1]∗[Ci−11]\left[ \begin{matrix} Ci \end{matrix} \right]=\left[ \begin{matrix} A&1 \end{matrix} \right]*\left[ \begin{matrix} Ci-1 \\ 1 \end{matrix} \right][Ci​]=[A​1​]∗[Ci−11​]

但是为了满足矩阵乘法的正确性(行数相同),我们补充一下两边矩阵

[Ci1]=[A101]∗[Ci−11]\left[ \begin{matrix} Ci \\ 1\end{matrix} \right]=\left[ \begin{matrix} A&1 \\ 0 & 1 \end{matrix} \right]*\left[ \begin{matrix} Ci-1 \\ 1 \end{matrix} \right][Ci1​]=[A0​11​]∗[Ci−11​]

定义初始矩阵为C0=[01]C0=\left[ \begin{matrix} 0 \\ 1 \end{matrix} \right]C0=[01​]
那么C1=[A101]∗[01]C1=\left[ \begin{matrix} A & 1 \\ 0 & 1 \end{matrix} \right]*\left[ \begin{matrix} 0 \\ 1 \end{matrix} \right]C1=[A0​11​]∗[01​]

那么CX=[A101]x∗[01]CX=\left[ \begin{matrix} A & 1 \\ 0 & 1 \end{matrix} \right]^{x}*\left[ \begin{matrix} 0 \\ 1 \end{matrix} \right]CX=[A0​11​]x∗[01​]

然后我们直接使用矩阵快速幂来迅速解决这道题即可

下面是具体的代码部分:

#include 
using namespace std;
typedef long long ll;
#define root 1,n,1
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
inline ll read() {ll x=0,w=1;char ch=getchar();for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';return x*w;
}
#define int long long
#define maxn 1000000
const double eps=1e-8;
#define	int_INF 0x3f3f3f3f
#define ll_INF 0x3f3f3f3f3f3f3f3f
int Mod,A,X;
int ans[10][10],x[10][10],c[10][10];
void x_pow() {for(int i=0;i<2;i++) {for(int j=0;j<2;j++) {c[i][j]=x[i][j];x[i][j]=0;}}for(int i=0;i<2;i++) {for(int j=0;j<2;j++) {for(int k=0;k<2;k++) {x[i][j]=(x[i][j]+c[i][k]*c[k][j]%Mod)%Mod;}		}}
}
void ans_pow() {for(int i=0;i<2;i++) {for(int j=0;j<1;j++) {c[i][j]=ans[i][j];ans[i][j]=0;}}for(int i=0;i<2;i++) {for(int j=0;j<1;j++) {for(int k=0;k<2;k++) {ans[i][j]=(ans[i][j]+x[i][k]*c[k][j]%Mod)%Mod;}}}
}
void juzhen_qpow(int k) {while(k) {if(k&1) ans_pow();k>>=1;x_pow();}
}
signed main() {A=read(),X=read(),Mod=read();x[0][0]=A;x[0][1]=1;x[1][0]=0;x[1][1]=1;ans[0][0]=0;ans[1][0]=1;juzhen_qpow(X);cout<

相关内容

热门资讯

中证A500ETF摩根(560... 8月22日,截止午间收盘,中证A500ETF摩根(560530)涨1.19%,报1.106元,成交额...
A500ETF易方达(1593... 8月22日,截止午间收盘,A500ETF易方达(159361)涨1.28%,报1.104元,成交额1...
何小鹏斥资约2.5亿港元增持小... 每经记者|孙磊    每经编辑|裴健如 8月21日晚间,小鹏汽车发布公告称,公司联...
中证500ETF基金(1593... 8月22日,截止午间收盘,中证500ETF基金(159337)涨0.94%,报1.509元,成交额2...
中证A500ETF华安(159... 8月22日,截止午间收盘,中证A500ETF华安(159359)涨1.15%,报1.139元,成交额...
科创AIETF(588790)... 8月22日,截止午间收盘,科创AIETF(588790)涨4.83%,报0.760元,成交额6.98...
创业板50ETF嘉实(1593... 8月22日,截止午间收盘,创业板50ETF嘉实(159373)涨2.61%,报1.296元,成交额1...
港股异动丨航空股大幅走低 中国... 港股航空股大幅下跌,其中,中国国航跌近7%表现最弱,中国东方航空跌近5%,中国南方航空跌超3%,美兰...
电网设备ETF(159326)... 8月22日,截止午间收盘,电网设备ETF(159326)跌0.25%,报1.198元,成交额409....
红利ETF国企(530880)... 8月22日,截止午间收盘,红利ETF国企(530880)跌0.67%,报1.034元,成交额29.0...