FFT版高精乘(存个板子什么都没写)

部署运行你感兴趣的模型镜像
#include<bits/stdc++.h>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<vector>
#include<iostream>
#define ll long long
#define re register
#define inf 0x7f7f7f7f
#define inl inline
#define sqr(x) (x*x)
//#define eps 1e-8
#define debug printf("debug\n");
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#pragma GCC optimize (2)
//#pragma G++ optimize (2)
using namespace std;
//const ll mod;
const double Pi=acos(-1.0);
const ll MAXN=2e6+10;
inl ll read() {
    re ll x = 0; re int f = 1;
    char ch = getchar();
    while(ch<'0'||ch>'9') { if(ch== '-' ) f = -1; ch = getchar(); }
    while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x * f;
}
inl char readc() {
    char ch=getchar();
    while(('z'<ch||ch<'a')&&('Z'<ch||ch<'A')) ch=getchar();
    return ch;
}
inl void write(re ll x){
    if(x>=10)write(x/10);
    putchar(x%10+'0');
}
inl void writeln(re ll x){
    if(x<0) {x=-x;putchar('-');}
    write(x); puts("");
}
inl ll gcd(re ll x,re ll y){while(y^=x^=y^=x%=y);return x;}
inl ll Lcm(re ll a,re ll b) {return a/gcd(a,b)*b;}
inl void FR() {
    freopen(".in","r",stdin);
    freopen(".out","w",stdout);
}
inl void FC() {
    fclose(stdin);
    fclose(stdout);
}
struct cmplex{
    double x,y;
    cmplex (double xx=0,double yy=0) {x=xx;y=yy;}
    cmplex operator + (const cmplex &ch) const {return cmplex(x+ch.x,y+ch.y);} 
    cmplex operator - (const cmplex &ch) const {return cmplex(x-ch.x,y-ch.y);} 
    cmplex operator * (const cmplex &ch) const {return cmplex(x*ch.x-y*ch.y,x*ch.y+y*ch.x);} 
}a[MAXN],b[MAXN];
ll n,ss[MAXN],l,r[MAXN],limit=1;
inl void fft(cmplex *a,ll type) {
    for(re ll i=0;i<limit;i++) {if(i<r[i]) swap(a[i],a[r[i]]);}//要迭代序列 
    for(re ll mid=1;mid<limit;mid<<=1) {
        cmplex Wn(cos(Pi/mid),type*sin(Pi/mid));//单位根 
        for(re ll R=mid<<1,j=0;j<limit;j+=R) {//R区间长,枚举到j 
            cmplex w(1,0);//
            for(re ll k=0;k<mid;k++,w=w*Wn) {//左半部分 
                cmplex x=a[j+k],y=w*a[j+mid+k];
                a[j+k]=x+y;a[j+mid+k]=x-y;
            }
        }
    }
}
char ssa[MAXN],ssb[MAXN];
int main() {
//  FR();
    n=read();n--;
    scanf("%s",ssa);scanf("%s",ssb);
    for(re ll i=0;i<=n;i++) a[i].x=ssa[n-i]-'0';
    for(re ll i=0;i<=n;i++) b[i].x=ssb[n-i]-'0';
    while(limit<=n+n) limit<<=1,l++;
    for(re ll i=0;i<limit;i++) {r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));} 
    fft(a,1);fft(b,1);
    for(re ll i=0;i<=limit;i++) a[i]=a[i]*b[i];
    fft(a,-1);
    ll top=(n<<1);
    for(re ll i=0;i<=top;i++) {
        ss[i]+=a[i].x/limit+0.5;
        if(ss[i]>=10) {
            ss[i+1]+=ss[i]/10,ss[i]%=10;
            if(i==top) top++;
        }
    }
    while(!ss[top]&&top>=1) top--;
    for(re ll i=top;~i;i--) write(ss[i]);
    putchar('\n');
//  FC();
    return 0;
}

 

转载于:https://www.cnblogs.com/20020723YJX/p/9492283.html

您可能感兴趣的与本文相关的镜像

AutoGPT

AutoGPT

AI应用

AutoGPT于2023年3月30日由游戏公司Significant Gravitas Ltd.的创始人Toran Bruce Richards发布,AutoGPT是一个AI agent(智能体),也是开源的应用程序,结合了GPT-4和GPT-3.5技术,给定自然语言的目标,它将尝试通过将其分解成子任务,并在自动循环中使用互联网和其他工具来实现这一目标

MATLAB主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性内容概要:本文主要介绍了一种在MATLAB环境下实现的主动噪声和振动控制算法,该算法针对较大的次级路径变化具有较强的鲁棒性。文中详细阐述了算法的设计原理与实现方法,重点解决了传统控制系统中因次级路径动态变化导致性能下降的问题。通过引入自适应机制和鲁棒控制策略,提升了系统在复杂环境下的稳定性和控制精度,适用于需要高精度噪声与振动抑制的实际工程场景。此外,文档还列举了多个MATLAB仿真实例及相关科研技术服务内容,涵盖信号处理、智能优化、机器学习等多个交叉领域。; 适合人群:具备一定MATLAB编程基础和控制系统理论知识的科研人员及工程技术人员,尤其适合从事噪声与振动控制、信号处理、自动化等相关领域的研究生和工程师。; 使用场景及目标:①应用于汽车、航空航天、精密仪器等对噪声和振动敏感的工业领域;②用于提升现有主动控制系统对参数变化的适应能力;③为相关科研项目提供算法验证与仿真平台支持; 阅读建议:建议读者结合提供的MATLAB代码进行仿真实验,深入理解算法在不同次级路径条件下的响应特性,并可通过调整控制参数进一步探究其鲁棒性边界。同时可参考文档中列出的相关技术案例拓展应用场景。
### 高精度法的算法原理 高精度法的核心思想是模拟手工计算中的竖式法方法,逐位相并处理进位。由于标准数据类型无法直接储和操作超大数值,因此通常使用数组或字符串来储每一位数字,并通过循环逐位进行运算。 对于多个高精度数相的情况,可以采用迭代的方式,依次将两个数相的结果作为中间结果,再与下一个数相,直到完成所有数的累积。在每一步法中,都需要处理进位、对齐位数以及结果储等问题[^2]。 ### 多个高精度数相的实现步骤 1. **输入读取**:读取要相高精度数的数量 $ n $ 以及每个数的具体值。 2. **初始化结果数组**:使用一个数组 `num` 来保当前的积结果,初始值为1(即单位元)。 3. **逐位相**: - 对于每一个数,创建一个新的临时数组用于储当前积。 - 使用嵌套循环进行逐位相,外层循环遍历当前数的每一位,内层循环遍历已有结果的每一位。 - 在每次相后,需要处理进位问题,并更新临时数组中的值。 4. **去除前导零**:在每一步相完成后,清理结果数组中的多余零,保留有效数字。 5. **输出结果**:最终将结果数组中的数字按高位到低位顺序输出。 ### C++ 实现代码示例 以下是一个完整的C++实现,用于计算多个高精度整数的积: ```cpp #include <iostream> #include <cstring> using namespace std; int main() { int n = 0; // 积数量 cin >> n; // 数的字符数组和整型数组 char numCArr[10][2001] = {}; int numArr[10][2001] = {}; // 初始化积容器 int num[2001] = {0}; num[0] = 1; num[1] = 1; // 输入并记录每个数的长度 for (int i = 0; i < n; i++) { cin >> numCArr[i]; numArr[i][0] = strlen(numCArr[i]); } // 倒序入整型数组 for (int i = 0; i < n; i++) { for (int j = 0; j < numArr[i][0]; j++) { numArr[i][numArr[i][0] - j] = numCArr[i][j] - '0'; } } // 逐个相 for (int k = 0; k < n; k++) { int c[num[0] + numArr[k][0]] = {0}; // 临时积数组 c[0] = num[0] + numArr[k][0]; // 核心法运算 for (int i = 1; i <= numArr[k][0]; i++) { int x = 0; for (int j = 1; j <= num[0]; j++) { c[i + j - 1] = num[j] * numArr[k][i] + x + c[i + j - 1]; x = c[i + j - 1] / 10; c[i + j - 1] %= 10; } c[i + num[0]] = x; } // 去除前导零 while (c[c[0]] == 0 && c[0] > 1) { c[0]--; } // 更新最终结果 memset(num, 0, sizeof(num)); for (int i = 0; i <= c[0]; i++) { num[i] = c[i]; } } // 输出结果 for (int i = num[0]; i > 0; i--) { cout << num[i]; } return 0; } ``` ### 算法优化与注意事项 - **空间优化**:尽量复用数组空间,避免频繁申请内。 - **时间复杂度**:该算法的时间复杂度大致为 $ O(n^2 \cdot m) $,其中 $ n $ 是数字的位数,$ m $ 是数的数量。对于非常大的数,可以考虑分治策略或快速傅里叶变换(FFT)进行优化。 - **负号处理**:如果支持负数,则需额外处理符号,并在最后输出时判断。 - **小数支持**:若需要支持小数,可以在法完成后统计小数点位置并插入到最终结果中。 ### 算法优势 高精度算法的优势在于能够灵活处理超出标准数据类型范围的数值,同时具备良好的可扩展性和可控性。它适用于密码学、科学计算、金融计算等需要极高精度的场景[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值