高精度

news/发布时间2024/5/11 4:50:05

高精度

因为c++没有大数类,最大的类型是 UNSIGNED LONG LONG 数值范围只有 \([0,2^{64}-1]\),没法满足需要,int128似乎不是正统语言中的内容,略。

所以高精度就是解决大数运算的技巧,把数组按位存储,一般从低位到高位。进制无所谓,但是常用10,为了节约复杂度有时会使用压位,即设 \(10^k\) 进制,可以在复杂度优化一个 \((压的位数)\),但是会遇到运算溢出的问题。

接下来讨论运算:

\(n,m\) 为两个高精数字位数,n为运算符左边的数,m为运算符右边的数

\(p\) 为低精数字,在运算符右边

加: \(O(n+m)\)

减:\(O(n+m)\)

朴素乘: \(O(nm)\) NTT乘:\(O((n+m)\log(n+m))\)

低精乘: \(O(n)\)

低精除:\(O(n)\)

低精取模:\(O(n)\)

模板如下:

const int Base=10;
typedef long long ll;
int r[1<<19];
int G=3,Gi=332748118;
void ntt(vector<ll> &a,int s,int INTT){for(int i=0;i<s;++i)if(i<r[i])swap(a[i],a[r[i]]);for(int len=2;len<=s;len<<=1){ll gn=qpow(INTT==-1?Gi:G,(mod-1)/len,mod);int k=len/2;for(int i=0;i<s;i+=len){ll g=1;for(int j=0;j<k;++j,g=g*gn%mod){ll tmp=a[i+j+k]*g%mod;a[i+j+k]=(a[i+j]-tmp+mod)%mod;a[i+j]=(a[i+j]+tmp)%mod;}}}if(INTT==-1){ll inv=qpow(s,mod-2,mod);for(int i=0;i<s;++i)a[i]=a[i]*inv%mod;}
}
struct Number{vector<ll> a;Number(){a.clear();}Number(int n){while(n){a.emplace_back(n%Base);n/=Base;}}void read(){string s;cin>>s;reverse(s.begin(),s.end());for(int i=0;i<(int)s.size();i+=1){int t=0;for(int j=min((int)s.size(),i+1)-1;j>=i;--j)t=t*10+s[j]-'0';a.emplace_back(t);}}Number operator + (int b){Number C;C.a=a;C.a[0]+=b;for(int i=0;i<(int)a.size();++i){if(C.a[i]>=Base){if(i+1<(int)a.size())C.a[i+1]+=C.a[i]/Base;else C.a.emplace_back(C.a[i]/Base);C.a[i]%=Base;}else break;}return C;}Number operator * (Number b){int n=a.size()-1+b.a.size()-1+1;int s=1;while(s<n)s<<=1;for(int i=0;i<s;++i)r[i]=(r[i>>1]>>1)|((i&1)*(s>>1));vector<ll> A=a,B=b.a;A.resize(s);B.resize(s);ntt(A,s,1);ntt(B,s,1);for(int i=0;i<s;++i)A[i]=A[i]*B[i]%mod;ntt(A,s,-1);Number C;C.a=A;for(int i=0;i<C.a.size()-1;++i){if(C.a[i]>=Base){C.a[i+1]+=C.a[i]/Base;C.a[i]%=Base;}}while(C.a.back()==0)C.a.pop_back();return C;}Number operator / (int b){Number C;C.a.resize(a.size(),0);ll t=0;for(int i=a.size()-1;i>=0;--i){t=t*Base+a[i];C.a[i]=t/b;t%=b;}while(C.a.back()==0)C.a.pop_back();return C;}void print(){if(a.size()==0){puts("0");return;}printf("%lld",a.back());for(int i=a.size()-2;i>=0;--i)printf("%lld",a[i]);puts("");}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/32184046.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

blog1 1--3周PTA训练总结

一.前言: 在学习过C语言之后,面向对象的程序设计在本学期如期开启。该课程的编程语言是java,java与所学过的C语言有诸多相似之处,与C语言课程所不同的是,这门课程注重的是面向对象,如果说C语言是语法的学习,那么java就是其实战应用的学习,这门课的学习更让我深刻的感受…

linux进程相关命令

知道一个程序的PID,可以进入目录/proc/PID查看进程的具体信息。 PS ps 命令是一个用于显示进程信息的常用命令。以下是 ps 命令的一些常用选项:-e:显示所有进程,包括系统进程。 -f:显示完整的进程信息,包括进程的详细信息。 -l:显示更多的列,包括进程的状态、CPU 使用情…

EasyUEFI 离线注册分析

离线注册分析仅做离线分析,文件版本5.3.0.2目录离线注册分析一、注册码分析register_CUpgradeDlg_21_id40_448DE0check_rsa_pubk_dec_47D1D0rsa_dec_47CEF0校验注册码信息sub_47D430二、离线激活码分析ok_440920unline_check_450320Init_490DD0校验激活码sub_491730py 一、注册…

springboot启动原理

启动类上的注解,会扫描路径下的类进容器进行实例化。这样访问时springmvc的dispa就可以访问到这个类了。 new DispatcherServlet(webapplication) springmvc需要一个web容器。这个容器参数,在startTomcat(applicationContext)方法里面传入。

第一次Blog

前言 第一次题目集是对类的设计,类与对象的使用和类与数组关联类的考察。第二次题目集是类与对象之间的创建以及运用的考察。第三次题目集是对类的封装性以及Java自带时间包的运用的考察。总而言之,三次题目集的题目量并不算大,题目集的难度也是比较中等。设计与分析这是答题…

记录Windows failed fast startup with error status 0xC00000D4.

1、电脑经常性卡死,查看event viewer 发现启动时一些error 不知道啥原因 看到https://answers.microsoft.com/en-us/windows/forum/windows8_1-performance/faststartup-issues-kernel-power-boot-and/69cc4b65-f847-4f4b-a0a0-b73f469a1ddf 这里说删除%windir%/prefetch文件夹…