首页 > 其他分享 >快速幂学习笔记

快速幂学习笔记

时间:2024-02-12 21:24:05浏览次数:27  
标签:frac ll 笔记 times 学习 ans quick return 快速

我们不妨先来看一道例题了解一下快速幂:

【模板】快速幂

A template.

观察到数据,\(a,b\le 2^{31}\),普通的乘法是肯定不行的。

因此考虑优化:快速幂。

什么是快速幂?

顾名思义,就是快速地求出幂(\(a^b\))。

怎么快速地求出幂?

将 \(a^b\) 展开,可得:

\[a^b = \underbrace{a\times a\times a\ldots\times a}_{b} \]

下面的 \(b\) 表示个数啦。

然后将相邻两项合并,得到:

\[a^b = \underbrace{a^2\times a^2\times a^2\ldots\times a^2}_{\frac{b}{2}} \]

这是会消除 \(\frac{b}{2}\) 个 \(a\),因此还有 \(\frac{b}{2}\) 个 \(a\)。

但是 \(b\) 可能是奇数,所以需要额外乘一个 \(a\),得到:

\[a^b = a\times \underbrace{a^2\times a^2\times a^2\ldots\times a^2}_{\frac{b}{2}} \]

因此,每次操作都会让 \(b\to \frac{b}{2}\),所以时间复杂度为 \(\mathcal O(\log{b})\),足以通过此题。

如果说 \(b\le 10^{10000}\),那就没办法了,得用更高深的算法(本蒟蒻也不会,qwq)。

代码实现

喜欢用函数的,可以定个 \(quickpow(a,b)\)。

  • 特判 \(a=0\) 的情况,直接返回 \(0\)。

    • 其实还有一种情况,就是 \(b=0\),但是任何数的 \(0\) 次方都等于 \(1\),因此不用顾虑。
  • 当 \(n > 0\) 才做,用一个 while() 循环。

    • 如果 \(n\bmod 2 =1\)(是奇数),那么 \(ans\) 处理多下的一个 \(a\),也就是 \(ans\gets ans\times a\)。

    • 然后 \(a\gets a^2\),\(b\gets \frac{b}{2}\),这就不用解释了吧。

  • 最后返回 \(ans\) 即可。

code

#define ll long long
inline ll quick_pow(ll a,ll b) {
	if(!a) return 0;
	ll ans=1;
	while(b){
		if(b&1)//位运算优化。
			ans=ans*a;
		a=a*a;
		b>>=1;//位运算优化 * 2。
	}
	return ans;
}

但这样并不能通过此题,因为 \(a^b\) 很有可能溢出。

那么就在上面的代码取模一下就行啦:

$\boxed{AC\ code}\ \ $局部

#define ll long long
inline ll quick_pow(ll a,ll b,ll p) {
	if(!a) return 0;
	ll ans=1;
	while(b){
		if(b&1) ans=ans*a%p;
		a=a*a%p;
		b>>=1;
	}
	return ans;
}

P10035 「FAOI-R2」Paint (A)

首先打出模拟代码找规律(别的大佬都是证明,就我找规律)。

i 从 1~10 的 answer:


1
4
13
40
121
364
1093
3280
9841
29524

咦,奇怪了,这好像哪里见过,不就是小学奥数的一道经典找规律吗?

递推公式:\(f_i = f_{i-1} \times 3+1\);

通项公式:\(f_i = (3^i - 1)\div 2\)。

求 \(3^i\) 次方不就是快速幂吗?

但是除法没有同余性质,所以需要求逆元。 不知道逆元的,建议去这里

代码就简单了:

ll quick_pow(ll x,ll p){//快速幂模板。
	ll res=x,ans=1;	
	while(p){
		if(p&1) ans=ans*res%MOD;
		res=res*res%MOD;
		p>>=1;
	}
	return ans;	
}
int main(){
	cin>>T;
    sum=quick_pow(2,MOD-2);//求逆元。
    while(T--){
        cin>>n;
        ssum=quick_pow(3,n);
        ssum=(ssum-1+MOD)%MOD;
	    cout<<ssum*sum%MOD<<endl;
    }
	return 0;
}

但好像费马小定理有一个条件,不过似乎数据都是 $\gcd(a,p) =1 $(doge。


好啦,就到这里吧。

标签:frac,ll,笔记,times,学习,ans,quick,return,快速
From: https://www.cnblogs.com/2021zjhs005/p/18014134

相关文章

  • 【笔记】矩阵快速幂
    前置芝士快速幂。什么是矩阵?矩阵,是由\(\begin{bmatrix}\end{bmatrix}\)组成的一个方阵(就这么理解好啦)。比如:\(\begin{bmatrix}1&2\\3&4\end{bmatrix}\)是一个\(2\times2\)的矩阵。矩阵乘法矩阵乘法的条件:仅当第\(1\)个矩阵的列数\(=\)第\(2\)个矩阵的行数才有......
  • boruvka 算法学习笔记
    boruvka算法就是最小生成树B算法。B算法的思路是每次对每个连通块,求出它能连出去的权值最小的边,然后再按边权从小到大合并。由于每次操作连通块数至少减半,所以复杂度是\(O(m\logn)\)。1.CF1305GKuroniandAntihype题意:长为\(n\)的数列\(a\),现在要选择全部数,每一次你......
  • C++——异常处理模块笔记
    异常处理是C++中的重要概念之一,用于处理在程序执行过程中可能发生的错误或异常情况。异常是指在程序执行过程中发生的一些不寻常的事件,例如除零错误、访问无效内存等。C++提供了一套异常处理机制,使得程序可以优雅地处理这些异常,提高程序的可靠性和健壮性。异常是一种程序......
  • [Blazor WebAssembly] 学习随笔——组件1.微信弹框(WXDialog)
    总有以下的需求:等待用户确认,就是有【确定】和【取消】按钮,有个标题和内容的弹框(比如:您确定要删除吗?)就是告知一下,就是上面的【取消】按钮不显示(比如:保存成功!)莫有按钮,几秒钟后自己消失,就是所谓的toast(比如:已完成)莫有按钮,需要发送命令才能消息(比如:数据加载中)一开始犯了经验主......
  • 假期学习实录
    2.04晚上放学后去和小学同学玩,挑战王者荣耀,用同学的星耀号打居然赢了,然后感觉是队友太强了(打到最后我5000经济队友1w+,被队友骂了,但是我们人多全部骂回去了)就去打钻石人机,结果赢了,看来我不是那个小学的时候白银都打不过的自己了!还玩了恐怖游戏(好像叫死寂),我觉得还好,不知道为啥他们......
  • 深度学习的始祖框架,grandfather级别的框架 —— Theano —— 示例代码学习(4)
    实战(DenseLayer):下面用本篇的内容,写一个全连接层,实现前向传播、反向传播和参数更新。并用它实现一个3输入1输出的单层感知机,拟合函数y=x0+x1+x2。代码:importtheanoimporttheano.tensorasTTimportnumpyasnpimportpylabclassDataset():def__init__(......
  • 江禾:零散媒体笔记
    零基础绘画练习排线,整齐几何体进阶把想画的东西画像,不断观察修改提高自己审美,分析好看的画为什么好看眼睛和画面要平行明确线条才能进步混剪素材预告片欧美预告片YouTube、Bilibili搜电影搜电影的替代网站纪录片《电影史话》《出神入化:电影剪辑的魔力》《工......
  • 深度学习的始祖框架,grandfather级别的框架 —— Theano —— 示例代码学习(3)
    实战:写一个卷积层ConvolutionLayer二维卷积的前向操作:代码:importtheano.tensorasTTimporttheanoimportnumpyasnp#fromtheano.tensor.shared_randomstreamsimportRandomStreamsIdentity=lambdax:xReLU=lambdax:TT.maximum(x,0.0)Sigmoid=lambda......
  • 二十八、实践中前端的一些笔记
    display:flex/inline-flex使用了display:flex/inline-flex属性后,子元素横向排列使用了display:flex属性后,父元素不设置宽度,宽度就是100%;不会被子元素宽度撑开;使用了display:inline-flex属性后,父元素不设置宽度,宽度就是所有的子元素宽度之和,会被子元素宽度撑开,实现宽度自......
  • 表达式学习
    1.intx=5>3:2:3.0  取精度高的类型,x的类型是double2.常量的声明:  constintx=1;3.块语句:intx=100;{Console.WriteLine(x);inty=200;Console.WriteLine(y);}Console.WriteLine(y);//访问不到y,y......