首页 > 其他分享 >快速幂优化高精度乘法

快速幂优化高精度乘法

时间:2024-12-21 13:53:31浏览次数:4  
标签:10 temp 高精度 int res back vector 优化 乘法

NOI 1.6 12

题目描述

题目给出的 \(n\) 最大可以取到 \(100\) ,即计算 \(2^{100}\) ,明显是超过 long long 的 \(2^{63}-1\),所以需要使用高精度来计算幂次方的乘法

  • 简单的高精度,即每次计算一个小整数乘上一个大整数

循环 \(n\) 次,每次对上一次的积都乘以 \(2\)

vector<int> ans = { 1 };//注意,需要对ans的第一位进行赋初值为1
for (int i = 1; i <= n; i++)
	ans = highdouble(ans);

然后就是简单高精度乘法的模板

vector<int> highdouble(vector<int> x) {
	vector<int> res;//定义返回数组
	int t = 0;//进位变量
	for (int i = 0; i < x.size(); i++) {
		t += 2 * x[i];//计算乘2的积
		res.push_back(t % 10);//取尾数放入
		t /= 10;
	}
	while (t) {//如果进位t还有值,就继续放入
		res.push_back(t % 10);
		t /= 10;
	}
	return res;//返回答案
}

以上的代码仅只用于大整数乘一个小整数,不能完成对两个大整数求积的操作、

简单的高精度计算的时间复杂度大约在 \(O(n^2)\) ,我们也可以使用快速幂的办法将时间复杂度优化到更低

  • 快速幂高精度计算
vector<int> quickpower(int b) {//快速幂函数
    vector<int> res, a;//使用vector来存储数据
    res.push_back(1);//对res第一项继续预处理
    a.push_back(2);//放入底数2
    while (b)//快速幂模板
    {
        if (b & 1) res = highplus(res, a);//使用高精度乘法计算
        a = highplus(a, a);//高精度倍增计算因子
        b >>= 1;
    }
    return res;
}

这里的高精度乘法需要计算两个大整数的积,采用错位相乘法

vector<int> highplus(vector<int>& x, vector<int>& y) {
    vector<int> temp(x.size() + y.size() + 1, 0);
    for (int i = 0; i < x.size(); i++)
        for (int j = 0; j < y.size(); j++)
            temp[i + j] += x[i] * y[j];
    int t = 0;
    for (int i = 0; i < temp.size(); i++) {
        t += temp[i];
        temp[i] = t % 10;
        t /= 10;
    }
    while (t > 0) {
        temp.push_back(t % 10);
        t /= 10;
    }
    while (temp.size() > 1 && temp.back() == 0) temp.pop_back();
    return temp;
}

其中,将 temp 赋值一个最大长度,即两个因子的长度和加 \(1\) ,并赋初值都为 \(0\)

循环两层计算相应位置上的乘积 temp[i + j] += x[i] * y[j]原理这里不做赘述

最后处理进位的问题,遍历整个 temp 数组,对每一位都继续进位操作

 t += temp[i];
 temp[i] = t % 10;
 t /= 10;
 
 while (t > 0) {//如果进位t还有值,就继续放入
    temp.push_back(t % 10);
    t /= 10;
 }

temp 数组去除前导 \(0\) 后返回高精度乘法的结果


经过实测,朴素的高精度乘法在规定的 \(1s\) 内最多只能计算到 \(2^{11438}\),而采用快速幂则可以计算到 \(2^{2^{15-1}}=2^{32767}\)

是一种极大的优化方案,如果我们的底数更大的话,快速幂的优势会变得更大

完整AC代码:

朴素算法

#include <vector>
#include <iostream>
using namespace std;

int n;
vector<int> ans = { 1 };

vector<int> highdouble(vector<int> x) {
	vector<int> res;
	int t = 0;
	for (int i = 0; i < x.size(); i++) {
		t += 2 * x[i];
		res.push_back(t % 10);
		t /= 10;
	}
	while (t) {
		res.push_back(t % 10);
		t /= 10;
	}
	return res;
}

int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++)
		ans = highdouble(ans);
	for (int i = ans.size() - 1; i >= 0; i--) cout << ans[i];
	return 0;
}

快速幂

#include <vector>
#include <iostream>
using namespace std;

int n;

vector<int> highplus(vector<int>& x, vector<int>& y) {
	vector<int> temp(x.size() + y.size() + 1, 0);
	for (int i = 0; i < x.size(); i++)
		for (int j = 0; j < y.size(); j++)
			temp[i + j] += x[i] * y[j];
	int t = 0;
	for (int i = 0; i < temp.size(); i++) {
		t += temp[i];
		temp[i] = t%10;
		t /= 10;
	}
	while (t > 0) {
		temp.push_back(t % 10);
		t /= 10;
	}
	while (temp.size() > 1 && temp.back() == 0) temp.pop_back();
	return temp;
}

vector<int> quickpower(int b) {
	vector<int> res, a;
	res.push_back(1);
	a.push_back(2);
	while (b)
	{
		if (b & 1) res = highplus(res, a);
		a = highplus(a, a);
		b >>= 1;
	}
	return res;
}

int main()
{
	cin >> n;
	auto ans = quickpower(n);
	for (int i = ans.size() - 1; i >= 0; i--) cout << ans[i];
	return 0;
}

标签:10,temp,高精度,int,res,back,vector,优化,乘法
From: https://www.cnblogs.com/dianman/p/18620685

相关文章

  • 一对一视频直播app开发,可优化性能的JavaScript技巧
    一对一视频直播app开发,10个高级的JavaScript技巧1、解构赋值解构赋值是一种从数组或对象中提取值并将其分配给变量的简洁方法,可以简化代码并提高可读性。对于数组,您可以使用方括号表示,而对于对象,则可以使用大括号表示。//解构数组const[firstItem,secondItem,...re......
  • 当大数据看板使用大量静态数据时,如何优化性能?
    当大数据看板使用大量静态数据时,前端开发的性能优化可以从以下几个方面进行:1.减少DOM数量分页或搜索展示:如果后端能够支持分页返回数据,前端可以优先通过后端分页返回数据,前端分页展示数据的方式进行处理,以减少需要渲染的DOM数量。虚拟列表:在前端仅渲染可视区域的内容,避免大量......
  • 1v1视频软件源码,如何优化快速排序算法低效问题?
    1v1视频软件源码,如何优化快速排序算法低效问题?快速排序快速排序也遵循分治的思想,它与归并排序不同的是,快速排序是原地排序,而且快速排序会先排序当前数组,再对子数组进行排序,它的算法步骤如下:1、哨兵划分:选取数组中最左端元素为基准数,将小于基准数的元素放在基准数左边,将......
  • 指数整合优化
    importakshareasakimportpandasaspdstart_date='2024-12-01'end_date='2024-12-20'#获取000300的历史行情数据df_000300=ak.index_zh_a_hist(symbol="000300")#获取sh000852的历史行情数据df_sh000852=ak.stock_zh_index_daily(symbol="......
  • React性能优化实战:从理论到落地的最佳实践
    "这个列表页怎么这么卡?"产品经理皱着眉头看着我。作为一个接手海外电商项目的前端开发者,我深知性能问题的重要性。特别是在东南亚市场,很多用户使用的是中低端手机,网络条件也不太理想。最近一个月,我带领团队对整个React应用进行了一次全面的性能优化,不仅解决了性能问题,还总......
  • PowerShell 脚本的作用是通过调用 NGEN (Native Image Generator) 工具来优化 .NET 程
    $Env:PATH=[Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory()[AppDomain]::CurrentDomain.GetAssemblies()|%{ $pt=$_.Location if(!$pt){continue} if($cn++){''} $na=Split-Path-Leaf$pt Write-Host-ForegroundColorY......
  • 【机器学习】股票价格预测:基于LSTM模型的完整实现与优化(附可运行代码及进阶操作)
    引言股票价格预测是一个复杂且具有挑战性的任务,传统的预测方法往往难以捕捉股票价格中的复杂关系。LSTM(长短期记忆网络)作为一种特殊的递归神经网络,因其能够处理时间序列中的长依赖问题,成为股票价格预测的有力工具。本文将详细介绍一个基于LSTM模型的股票价格预测项目,并结合实......
  • 《 C++ 点滴漫谈: 十 》揭秘 C++ struct 的潜力:内存布局、继承、优化,你都掌握了吗?
    摘要本文全面解析了C++中的struct关键字,从其基本概念到高级应用,涵盖了struct的成员与访问控制、构造函数与析构函数、继承与多态,以及内存布局和现代C++的特性扩展。此外,文章详细探讨了struct与class的异同、与union的对比,并剖析了常见的误区与陷阱。结合丰富......
  • 使用 Assert 工具类优化业务逻辑判断
    使用Assert工具类优化业务逻辑判断在项目中,常常需要进行判空或业务逻辑判断,进而抛出异常处理。例如,检查用户是否登录、设备信息是否正确、用户是否有权限等。示例代码(未优化)java复制代码//查看是否登录LoginUserloginUser=getLoginUser();if(loginUser==null......
  • 关于 Sysprep、小鱼儿yr系统封装优化设置辅助工具、全自动系统封装工具 v5.5.3.6、系
    关于Sysprep、小鱼儿yr系统封装优化设置辅助工具、全自动系统封装工具v5.5.3.6、系统封装助手v2.0正式版、EasySysprep5Plus和系统封装首席执行官的对比分析表格,主要从功能、自动化程度、适用场景等角度进行比较。工具名称Sysprep小鱼儿yr系统封装优化设置辅助工具......