没什么好说的,今天又考了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 = ;
const real pi = 3.1415926535897932;
struct Complex
{
real x,y;
Complex(){}
Complex(real x,real y=):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=;i<l;i++)
{
x=;
for (int j=,k=(l>>);j<l;j<<=,k>>=)
if (i&j)x+=k;
if (x<i)
swap(g[x],g[i]);
}
Complex wt,w,tmp;
for (int i=;i<l;i<<=)
{
wt=Complex(cos(pi/i*p),sin(pi/i*p));
for (int j=;j<l;j+=(i<<))
{
Complex w=Complex(,);
for (int k=;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=;i<l1;i++)
g1[(l1-i-)/]=g1[(l1-i-)/].x*+s1[i]-'';
for (int i=;i<l2;i++)
g2[(l2-i-)/]=g2[(l2-i-)/].x*+s2[i]-'';
int l=max(l1,l2)/+;
while (l!=(l&(-l)))l-=l&(-l);
l<<=;
FFT(g1,l,);
FFT(g2,l,);
for (int i=;i<l;i++)rr[i]=g1[i]*g2[i];
FFT(rr,l,-);
for (int i=;i<l;i++)
{
rr[i]=rr[i]/l;
lst[i]=(int)(rr[i].x+0.5);
}
for (int i=;i<l;i++)
{
lst[i+]+=lst[i]/;
lst[i]%=;
}
while (l> && !lst[l-])l--;
printf("%d",lst[l-]);
for (int i=l-;i>=;i--)
printf("%04d",lst[i]);
printf("\n");
}
}
namespace task2
{
typedef long long qword;
const int maxn = ;
const qword p = ;
char s1[maxn],s2[maxn];
qword g1[maxn],g2[maxn];;
qword rr[maxn];
qword pow_mod(qword x,qword y)
{
qword ret=;
while (y)
{
if (y&)ret=ret*x%p;
x=x*x%p;
y>>=;
}
return ret;
}
void FFT(qword g[],int l,int f)
{
int x=;
for (int i=;i<l;i++)
{
x=;
for (int j=,k=(l>>);j<l;j<<=,k>>=)
if (i&j)x+=k;
if (i<x)
swap(g[i],g[x]);
}
qword w,wt,tmp;
for (int i=,t=;i<l;i<<=,t++)
{
wt=pow_mod(,**(<<(-t)))%p;
if (f==-)
//wt=-wt;
wt=pow_mod(wt,p-);
for (int j=;j<l;j+=(i<<))
{
w=;
for (int k=;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=;i<l1;i++)
g1[i]=s1[l1-i-]-'';
for (int i=;i<l2;i++)
g2[i]=s2[l2-i-]-'';
int l=max(l1,l2);
while (l!=(l&(-l)))l-=l&(-l);
l<<=;
FFT(g1,l,);
FFT(g2,l,);
for (int i=;i<l;i++)rr[i]=g1[i]*g2[i]%p;
FFT(rr,l,-);
qword invl=pow_mod(l,p-);
for (int i=;i<l;i++)rr[i]=(rr[i]*invl%p+p)%p;
for (int i=;i<l;i++)
{
rr[i+]+=rr[i]/;
rr[i]%=;
}
while (l> && ! rr[l-])l--;
for (int i=l-;i>=;i--)
printf("%d",(int)rr[i]);
}
} int main()
{
freopen("input.txt","r",stdin);
task1::main();
task2::main();
}

再写FFT模板的更多相关文章

  1. FFT模板(多项式乘法)

    FFT模板(多项式乘法) 标签: FFT 扯淡 一晚上都用来捣鼓这个东西了...... 这里贴一位神犇的博客,我认为讲的比较清楚了.(刚好适合我这种复数都没学的) http://blog.csdn.n ...

  2. P1919 【模板】A*B Problem升级版 /// FFT模板

    题目大意: 给定l,输入两个位数为l的数A B 输出两者的乘积 FFT讲解 这个讲解蛮好的 就是讲解里面贴的模板是错误的 struct cpx { double x,y; cpx(double _x= ...

  3. HDU 1402 A * B Problem Plus (FFT模板题)

    FFT模板题,求A*B. 用次FFT模板需要注意的是,N应为2的幂次,不然二进制平摊反转置换会出现死循环. 取出结果值时注意精度,要加上eps才能A. #include <cstdio> ...

  4. switch case :在JDK 7中,又加入了对String类型的支持,从此不用再写If-Else来判断字符串了

    switch的case语句可以处理int,short,byte,char类型的值, 因为short,byte,char都会转换成int进行处理,这一点也可以从生成的字节码看出. char a = 'e ...

  5. 传递的值是this,在js里就不用再写$(this)

    <input class="editinput" value="${detail.earlymoneyrmb}" name="earlymone ...

  6. 以前写SpringMVC的时候,如果需要访问一个页面,必须要写Controller类,然后再写一个方法跳转到页面,感觉好麻烦,其实重写WebMvcConfigurerAdapter中的addViewControllers方法即可达到效果了

    以前写SpringMVC的时候,如果需要访问一个页面,必须要写Controller类,然后再写一个方法跳转到页面,感觉好麻烦,其实重写WebMvcConfigurerAdapter中的addViewC ...

  7. hdu1402(大数a*b&fft模板)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1402 题意: 给出两个长度1e5以内的大数a, b, 输出 a * b. 思路: fft模板 详情参 ...

  8. 再写一篇tps限流

    再写一篇tps限流 各种限流算法的称呼 网上有很多文章介绍限流算法,但是对于这些算法的称呼与描述也是有点难以理解.不管那么多了.我先按我理解的维度梳理一下. 主要维度是:是正向计数还是反向计数.是定点 ...

  9. 缓存与数据库一致性之二:高并发下的key重建(先淘汰cache再写db)的问题

    一.为什么数据会不一致 回顾一下上一篇文章<缓存与数据库一致性之一:缓存更新设计>中对缓存.数据库进行读写操作的流程. 写流程: (1)先淘汰cache (2)再写db 读流程: (1)先 ...

随机推荐

  1. linux解压命令笔记

    转载:http://www.cnblogs.com/eoiioe/archive/2008/09/20/1294681.html .tar 解包:tar xvf FileName.tar打包:tar ...

  2. linux版本的区分

    linux每个版本有好几种方式,刚学习的时候还不明白,了解了一下终于知道了 如下,以CentOS为例 1.CentOS系统镜像有两个,安装系统只用到第一个镜像即CentOS-6.x-i386-bin- ...

  3. 【原】NGUI中的UIAnchor脚本功能

    UIAnchor的功能是把对象锚定在屏幕的边缘(左上,左中,左下,上,中,下,右上,右中,右下),或缩放物体使其匹配屏幕的尺寸. 在1.90版本后,拉长(缩放)的功能被放到UIStretch中,UIA ...

  4. php处理字符串常用函数

    1查找字符位置函数: strpos($str,search,[int]):查找search在$str中的第一次位置从int开始: stripos($str,search,[int]):函数返回字符串在 ...

  5. zz存储系统中缓存的三种类型

    三种基本类型的缓存:绕写式(write-around),直写式(write-through)和回写式(write-back). 绕写式(write-around)缓存意味着所有数据首先被写入到硬盘区, ...

  6. C#学习笔记15:字符串、文件、目录的操作方法

    字符串:不可变性 String str=”abcdf”; 将字符串转换为char数组:ToCharArray(); Char[] ch=str.ToCharAarray(); 将char数组转换为字符 ...

  7. linux---基本查找命令

    基本查找命令 一.文件查找命令:find 最大特点:功能强大,可以使用文件的各种属性作为查找条件来查找文件 文件属性:文件权限.文件所有者.文件大小.修改时间.文件类型 语法:find[起始查找目录] ...

  8. items 与iteritems

    dict的items函数返回的是键值对的元组的列表,而iteritems使用的是键值对的generator. items当使用时会调用整个列表 iteritems当使用时只会调用值. >> ...

  9. ###STL学习--vector

    点击查看Evernote原文. #@author: gr #@date: 2014-08-11 #@email: forgerui@gmail.com vector的相关问题.<stl学习> ...

  10. ios简单数据库运用

    一.添加类 二.打开数据库 三.创表 四.插入数据 五.取出数据 一.添加类 1.在设置Linked Frameworks and Libraries 中,点加号并添加libsqlite3.0.dyl ...