再写FFT模板

  没什么好说的,今天有考了FFT(虽然不用FFT也能过)但是确实有忘了怎么写FFT了,于是乎只有重新写一遍FFT模板练一下手了。第一部分普通FFT,第二部分数论FFT,记一下模数2^23*7*17+1

  

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef double real;
namespace task1
{
        const int maxn = 110000;
        const real pi = 3.1415926535897932;
        struct Complex
        {
                real x,y;
                Complex(){}
                Complex(real x,real y=0):x(x),y(y){}
        };
        Complex operator + (Complex c1,Complex c2)
        {
                return Complex(c1.x+c2.x,c1.y+c2.y);
        }
        Complex operator - (Complex c1,Complex c2)
        {
                return Complex(c1.x-c2.x,c1.y-c2.y);
        }
        Complex operator * (Complex c1,Complex c2)
        {
                return Complex(c1.x*c2.x-c1.y*c2.y,c1.y*c2.x+c1.x*c2.y);
        }
        Complex operator / (Complex c1,real k)
        {
                return Complex(c1.x/k,c1.y/k);
        }
        char s1[maxn],s2[maxn];
        Complex g1[maxn],g2[maxn],rr[maxn];
        int lst[maxn];
        void FFT(Complex g[],int l,int p)
        {
                int x;
                for (int i=0;i<l;i++)
                {
                        x=0;
                        for (int j=1,k=(l>>1);j<l;j<<=1,k>>=1)
                                if (i&j)x+=k;
                        if (x<i)
                                swap(g[x],g[i]);
                }
                Complex wt,w,tmp;
                for (int i=1;i<l;i<<=1)
                {
                        wt=Complex(cos(pi/i*p),sin(pi/i*p));
                        for (int j=0;j<l;j+=(i<<1))
                        {
                                Complex w=Complex(1,0);
                                for (int k=0;k<i;k++)
                                {
                                        tmp=g[j+k];
                                        g[j+k]=g[j+k]+g[i+j+k]*w;
                                        g[i+j+k]=tmp-g[i+j+k]*w;
                                        w=w*wt;
                                }
                        }
                }
        }
        void main()
        {
                int l1,l2;
                scanf("%s",s1);
                scanf("%s",s2);
                l1=(int)strlen(s1);
                l2=(int)strlen(s2);
                for (int i=0;i<l1;i++)
                        g1[(l1-i-1)/4]=g1[(l1-i-1)/4].x*10+s1[i]-‘0‘;
                for (int i=0;i<l2;i++)
                        g2[(l2-i-1)/4]=g2[(l2-i-1)/4].x*10+s2[i]-‘0‘;
                int l=max(l1,l2)/4+1;
                while (l!=(l&(-l)))l-=l&(-l);
                l<<=2;
                FFT(g1,l,1);
                FFT(g2,l,1);
                for (int i=0;i<l;i++)rr[i]=g1[i]*g2[i];
                FFT(rr,l,-1);
                for (int i=0;i<l;i++)
                {
                        rr[i]=rr[i]/l;
                        lst[i]=(int)(rr[i].x+0.5);
                }
                for (int i=0;i<l;i++)
                {
                        lst[i+1]+=lst[i]/10000;
                        lst[i]%=10000;
                }
                while (l>1 && !lst[l-1])l--;
                printf("%d",lst[l-1]);
                for (int i=l-2;i>=0;i--)
                        printf("%04d",lst[i]);
                printf("\n");
        }
}
namespace task2
{
        typedef long long qword;
        const int maxn = 10000;
        const qword p = 998244353;
        char s1[maxn],s2[maxn];
        qword g1[maxn],g2[maxn];;
        qword rr[maxn];
        qword pow_mod(qword x,qword y)
        {
                qword ret=1;
                while (y)
                {
                        if (y&1)ret=ret*x%p;
                        x=x*x%p;
                        y>>=1;
                }
                return ret;
        }
        void FFT(qword g[],int l,int f)
        {
                int x=0;
                for (int i=1;i<l;i++)
                {
                        x=0;
                        for (int j=1,k=(l>>1);j<l;j<<=1,k>>=1)
                                if (i&j)x+=k;
                        if (i<x)
                                swap(g[i],g[x]);
                }
                qword w,wt,tmp;
                for (int i=1,t=1;i<l;i<<=1,t++)
                {
                        wt=pow_mod(3,7*17*(1<<(23-t)))%p;
                        if (f==-1)
                                //wt=-wt;
                                wt=pow_mod(wt,p-2);
                        for (int j=0;j<l;j+=(i<<1))
                        {
                                w=1;
                                for (int k=0;k<i;k++)
                                {
                                        tmp=g[j+k];
                                        g[j+k]=(g[j+k]+g[i+j+k]*w)%p;
                                        g[i+j+k]=(tmp-g[i+j+k]*w)%p;
                                        w=w*wt%p;
                                }
                        }
                }
        }
        void main()
        {
                int l1,l2;
            //    for (int i=0;i<5;i++)
            //            printf("[1/%d*pi]:%d\n",(1<<i),7*17*(1<<(23-i)));
                scanf("%s",s1);
                scanf("%s",s2);
                l1=(int)strlen(s1);
                l2=(int)strlen(s2);
                for (int i=0;i<l1;i++)
                        g1[i]=s1[l1-i-1]-‘0‘;
                for (int i=0;i<l2;i++)
                        g2[i]=s2[l2-i-1]-‘0‘;
                int l=max(l1,l2);
                while (l!=(l&(-l)))l-=l&(-l);
                l<<=2;
                FFT(g1,l,1);
                FFT(g2,l,1);
                for (int i=0;i<l;i++)rr[i]=g1[i]*g2[i]%p;
                FFT(rr,l,-1);
                qword invl=pow_mod(l,p-2);
                for (int i=0;i<l;i++)rr[i]=(rr[i]*invl%p+p)%p;
                for (int i=0;i<l;i++)
                {
                        rr[i+1]+=rr[i]/10;
                        rr[i]%=10;
                }
                while (l>1 && ! rr[l-1])l--;
                for (int i=l-1;i>=0;i--)
                        printf("%d",(int)rr[i]);
        }
}

int main()
{
        freopen("input.txt","r",stdin);
        task1::main();
        task2::main();
}
时间: 2024-12-21 13:02:50

再写FFT模板的相关文章

在require回调函数中执行tooltipvalidator.init不需要另外再写逻辑

尽管每个人学习开发的过程会不一样,然而无论如何,系统的学习方法对每个学习者来说都是至关重要的.对于初学者,应该经常向资深的游戏开发者学习,通过他们的直播和视频,学习游戏开发的技巧.你从这些专家们身上学到的东西越多,你就可以越快成为优秀的开发者. 通过proceed()方法可以调用目标对象的相应方法,从而实现对目标方法的完全控制! angular2 的依赖注入包含了太多的内容,其中的一个重点就是注入器,而注入器又非常难理解,今天我们不深入介绍注入器的内容,可以参考官方文档,我们今天来说注入器的层级

fft模板 HDU 1402

1 // fft模板 HDU 1402 2 3 #include <iostream> 4 #include <cstdio> 5 #include <cstdlib> 6 #include <algorithm> 7 #include <vector> 8 #include <math.h> 9 #include <memory.h> 10 #include <bits/stdc++.h> 11 using

hdu1402(大数a*b&amp;fft模板)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1402 题意: 给出两个长度1e5以内的大数a, b, 输出 a * b. 思路: fft模板 详情参见: http://blog.csdn.net/sdj222555/article/details/9786527  https://wenku.baidu.com/view/8bfb0bd476a20029bd642d85.html 可以将 a, b 看成两个多项式, 每个数位为一项, 每一位上的

FFT模板

  #include <cstdio> #include <cmath> #include <cstring> using namespace std; const double pi = acos(-1.0); const int maxn = 500005; struct complex { double r,i; complex(double r = 0.0,double i = 0.0) :r(r),i(i) {} inline complex operator

第二十二篇:再写Windows驱动,再玩Windbg---NET

2011年到现在,就没再怎么搞过Windows驱动了. 最近, 由于项目需要, 试着改一改一个显卡驱动(KMDOD), 从实践上证明, 我在理论上对一个驱动的架构的正确与否.(USB Display = KMDOD + AVStream). 其中, KMDOD是完成显示的部分功能, 完成其中的VidPN(Video present network), 将驱动中原来的POST物理设备转变为USB物理设备. 而AVStream之所以这样提出, 完成是由于USB Video class的启发, 要不然

为了免费拿到微软的年底发布会的门票,只有厚着脸皮再写些 Microsoft Dynamics CRM 2013文章分享了

奔跑中的2015, 为了免费拿到微软的每年年底发布会的门票和IT相关的证书,没有办法,本人大专学历太低,最近本人所以在的城市政府有人才奖厉计划,就因要求本科及以上学历,都跟本人无缘了,所以只有厚着脸皮再写些 Microsoft Dynamics CRM 2013文章分享了,争取能在微软得到证书,肯定自已了. 前几个月在家里找到2012年的一张微软北京技术大会的门票,想想今年应该写点什么技术文章,再免费参加一次会议吧,想想写什么方面的呢,微软的office,server,数据库等专家太多了,写不过

最小生成树,POJ和HDU几道题目的解题报告(基于自己写的模板)

首先POJ题目: 链接:1251 Jungle Roads 题目大意:纯求最小生成树,结果为最小权值边的和.采用邻接表 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <queue> 5 using namespace std; 6 7 #define maxn 30 //最大顶点个数 8 int n; //顶点数,边数 9 10 struct arcn

[hdu1402]大数乘法(FFT模板)

题意:大数乘法 思路:FFT模板 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81

【BZOJ 2179】【FFT模板】 FFT快速傅立叶

2179: FFT快速傅立叶 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 1595 Solved: 792 [Submit][Status][Discuss] Description 给出两个n位10进制整数x和y,你需要计算x*y. Input 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数为n的正整数y. Output 输出一行,即x*y的结果. Sample Input 1 3 4 Sample Output