XCPC历险记第二章!带你玩转高精度、前缀和与差分!

本文深入探讨了高精度计算,包括大数的加减乘除,并提供了详细的算法实现。接着讲解了前缀和的概念及其作用,以及二维前缀和的计算方法。此外,还介绍了差分运算及其在数组操作中的应用,特别是二维差分的实现。通过实例和代码解析,帮助读者理解这些核心概念。
摘要由CSDN通过智能技术生成


在这里插入图片描述

一、高精度剖析与例题讲解

      高精度问题是一类处理长度(位数)很长的正整数的运算问题(以下均讨论非负数)。在学习具体的问题之前,我们首先要学习超长整数是如何存储的。对于超长整数,用某种数据类型来存储其实是行不通的,我们会把它的每一位存到数组里。在存储时,数组的小下标存低位,大下标存高位。比如若把123456(当然它不是超长整数,我们只是举个例子)存到数组里,那么就是6 5 4 3 2 1。这样做是因为加减乘除可能涉及到进位,而在数组尾部进行数据的修改是比较容易的。注意:不要混淆位数和数值!比如说,若一个数的数值<=10,那么它的取值范围是0-10;若一个数的长度<=10,那么它的取值范围是0-9999999999。
      高精度问题主要分为以下几类:

1.A+B(A,B位数很大,如1e6级别)

让我们先来回忆一下竖式加法的流程:
在这里插入图片描述

这里的ti(i = 0,1,2,3)表示进位,因此ti = 0或1。我们可以发现,Ci = (Ai + Bi + ti)%10。因此要实现超长整数相加,只需要把数组对应位置的数以及进位数加起来再模10,就可以得到新数字的每一位。 那么就让我们来看看代码如何实现吧!
在这里插入图片描述

#include <iostream>
#include<vector>
using namespace std;
//传引用,防止多开空间
vector<int>add(vector<int>&A,vector<int>&B)
{
   
    vector<int> C;
    //保存进位
    int t = 0;
    for(int i = 0;i<A.size()||i<B.size();i++)
    {
   
        if(i<A.size())    t+=A[i];
        if(i<B.size())    t+=B[i];
        C.push_back(t%10);
        //保存进位
        t/=10;
    }
    //如果到最后还有进位,就在C最后面补上一个1
    if(t)   C.push_back(1);
    return C;
}
int main()
{
   
    //用字符串的形式读数,可以拿到每一位
    string a,b;
    //定义大小可变化的数组
    vector<int> A,B;
    cin>>a>>b;
    //由于读进来的形式是字符,因此为了拿到那一位,我们要减去偏移量,即字符0的ASCII码值。
    //此外,我们要把数据倒着读进数组。
    for(int i = a.size()-1;i>=0;i--)    A.push_back(a[i]-'0');
    for(int i = b.size()-1;i>=0;i--)    B.push_back(b[i]-'0');
    
    vector<int> C = add(A,B);
    //倒着打印
    for(int i = C.size()-1;i>=0;i--)    printf("%d",C[i]);
    
    return 0;
}

一定要好好看注释哦,作者想说的都在注释里啦!如果你感觉阅读本段代码有困难,不妨先看看这个——[
C++vector快速入门

2.A-B(A,B位数很大,如1e6级别)

数据的存储方式同上。那么相减的算法思想是怎样的呢?我们通过竖式计算图来观察一下:
在这里插入图片描述
我们可以发现,与加法不同的是减法需要借位。假设上一位借该位t(t=0或1),那么

>=0 不需要借位 那么直接减就可以 得到Ai - Bi - t
Ai - Bi - t
<0 那么需要借位,也就是+10,得到Ai -Bi - t + 10

在这里插入图片描述

#include<iostream>
using namespace std;
#include<vector>
//判断是否有 A>=B
bool cmp(vector<int>&A,vector<int>&B)
{
   
    if(A.size()!=B.size())  return A.size()>B.size();
    for(int i = A.size()-1;i>=0;i--)
    {
   
        if(A[i]!=B[i])  return A[i]>B[i];
    }
    return true;
}

//C = A - B
//这里已经保证A>=B了
vector<int> sub(vector<int>&A,vector<int>&B)
{
   
    vector<int> C;
    //由于已经保证A>=B,所以A.size()>=
  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值