题目大意:高精度乘法。

    fft的实现貌似有很多种,咱先写的是一种递归的fft,应该算是比较快的了吧。参考了 Evil君 的代码,那个运算符重载看的咱P党泪流满面。 (没想到P竟然有运算符重载咩...)
    先背模板再理解0.0
    以下是待补的对模板的理解
{
    其实讲的主要的关键就是如何递归,他记录了一个深度 t,一个左边界s(开区间的),和一个最后FFT的结果的数组a。
 
    他实际上是在递归的过程中就已经计算好了叶子的了,所以复杂度是O(nlogn),咱们来看看咱们如何通过这些递归变量计算出咱们需要的需要计算的(实际上弄出这个来这个算法就基本上可以了)。
  
    主要的代码段就是这里:
    {  
 for i:=0 to n>>(t+1)-1 do
   begin
     p:=i<<(t+1)+s;
     wt:=w[i<<t]*a[p+1<<t];
     tt[i]:=a[p]+wt;
     tt[i+n>>(t+1)]:=a[p]-wt;
   end;
  for i:=0 to n>>t-1 do a[i<<t+s]:=tt[i];
    回顾之前的FFT算法,咱们在深度为K的时候,将A分成两半,实际上可以看做是将A按照二进制的第K位是否为1分成两半的。以这个咱们发现..咱们记录的那个S实际上就是当前进行FFT所包含的A的元素的下标二进制的公共部分....然后当前深度的合并的元素实际上就在这里面,且就是在S的二进制基础上在最高位加上一个二进制,即0~ n shr t,即S+[0,n shr t-1]shl (t+1)(这个实际上就是代码中的p了 0v0)
    咱们攻克了第二行,可是第一行的那个循环还是有点不对劲的感觉...按道理应该是 0~n shr t-1的,可是这里是0~n shr t shr 1-1,实际上这就是要用蝴蝶操作了,所以只需要枚举一半的量,也就是说,这里实际上要确定两个进行蝴蝶操作的A的下标的二进制关系。
    首先确定一点,咱们在整个算法中用到a的地方仅仅在于划分,所以咱们用它们的对应的位置存储y[],然后之后都是直接用 Y0+xY1这样的形式来计算,所以咱们要清楚循环里面存的实际上应该是y。当前所要计算的应该是 w(n>>t,)系列的,咱们将它们存储到对应的区间里面。(其实就是原来的!!!)
    对于某一个区间给定的 s,t,咱们首先可以计算出这个里面涉及到的 a[],为[s,s+n>>t],然后分段,一段就是 i+1<<(t+1),其对应的应该就是+1<<t.
   }
   吐槽:这个模板还需要优化额..为什么感觉和普通的高精度比还是不太行= =
   (不过去wikioi的那个10^5的测试貌似跑的还是蛮快的...但是目测常数略大...,因为10^5的数要800ms+跑完)

========================

program fft;
type cp=record x,y:double;end;
     arr=array[0..1 shl 14]of cp;
var a,b,tt,w:array[0..1 shl 14]of cp;
    c:array[0..1000010]of longint;
    n,tot1,tot2:longint;
 
operator *(var a,b:cp)c:cp;
begin c.x:=a.x*b.x-a.y*b.y;c.y:=a.x*b.y+a.y*b.x;end;
operator +(var a,b:cp)c:cp;
begin c.x:=a.x+b.x;c.y:=a.y+b.y;end;
operator -(var a,b:cp)c:cp;
begin c.x:=a.x-b.x;c.y:=a.y-b.y;end;
 
procedure dft(var a:arr;s,t:longint);
var i,p:longint;
    wt:cp;
begin
  if n>>t=1 then exit;
  dft(a,s,t+1);
  dft(a,s+1<<t,t+1);
  for i:=0 to n>>(t+1)-1 do
   begin
     p:=i<<(t+1)+s;
     wt:=w[i<<t]*a[p+1<<t];
     tt[i]:=a[p]+wt;
     tt[i+n>>(t+1)]:=a[p]-wt;
   end;
  for i:=0 to n>>t-1 do a[i<<t+s]:=tt[i];
end;
 
procedure init;
var ch:char;
    i,k:longint;
    j:cp;
begin
  read(ch);tot1:=0;tot2:=0;
  while (ord(ch)>=ord('0'))and(ord(ch)<=ord('9')) do
   begin
     a[tot1].x:=ord(ch)-ord('0');
     read(ch);
     inc(tot1);
   end;
  read(ch);
  while (ord('0')<=ord(ch)) and(ord(ch)<=ord('9')) do
   begin
     b[tot2].x:=ord(ch)-ord('0');
     read(ch);
     inc(tot2);
   end;
  dec(tot1);dec(tot2);
  for i:=0 to tot1 shr 1 do
   begin
     j:=a[i];a[i]:=a[tot1-i];a[tot1-i]:=j;
   end;
  for i:=0 to tot2 shr 1 do
   begin
     j:=b[i];b[i]:=b[tot2-i];b[tot2-i]:=j;
   end;
  if tot1<tot2 then tot1:=tot2;
  n:=1;
  while n>>1<(tot1+1) do n:=n shl 1;
  for i:=0 to n-1 do w[i].x:=cos(pi*2*i/n);
  for i:=0 to n-1 do w[i].y:=sin(pi*2*i/n);
  dft(a,0,0);dft(b,0,0);
  for i:=0 to n-1 do w[i].y:=-w[i].y;
  for i:=0 to n-1 do a[i]:=a[i]*b[i];
  dft(a,0,0);
  fillchar(c,sizeof(c),0);
  for i:=0 to n-1 do
   begin
     c[i]:=c[i]+round(a[i].x/n);
     c[i+1]:=c[i] div 10;
     c[i]:=c[i] mod 10;
   end;
  i:=n;
  while (c[i]=0)and(i>0) do dec(i);
  for k:=i downto 0 do write(c[k]);
end;
 
begin
  init;
 end.

转自 z55250825 的几篇关于FFT的博文(二)的更多相关文章

  1. 转自 z55250825 的几篇关于FFT的博文(三)

    题目大意:给出n个数qi,定义 Fj为        令 Ei=Fi/qi,求Ei.      其实这道题就是看到有FFT模板才觉得有必要学一下的...    所以实际上就是已经知道题解了... = ...

  2. 转自 z55250825 的几篇关于FFT的博文(一)

        关于FFT,咱们都会迫不及待地 @  .....(大雾)(貌似被玩坏了...)    .....0.0学习FFT前先orz FFT君.         首先先是更详细的链接(手写版题解点赞0v ...

  3. 关于Java多线程的线程同步和线程通信的一些小问题(顺便分享几篇高质量的博文)

    Java多线程的线程同步和线程通信的一些小问题(顺便分享几篇质量高的博文) 前言:在学习多线程时,遇到了一些问题,这里我将这些问题都分享出来,同时也分享了几篇其他博客主的博客,并且将我个人的理解也分享 ...

  4. Java多线程编程实战指南(核心篇)读书笔记(二)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76651408冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  5. 转一篇老外写的博文:Android automated testing (Robotium)

    Robotium的中文资料甚少,只得求助于老外,发现了一篇不错的文章:https://blog.codecentric.de/en/2011/03/android-automated-testing- ...

  6. iOS开发——语法篇OC篇&高级语法精讲二

    Objective高级语法精讲二 Objective-C是基于C语言加入了面向对象特性和消息转发机制的动态语言,这意味着它不仅需要一个编译器,还需要Runtime系统来动态创建类和对象,进行消息发送和 ...

  7. Python开发【第十三篇】:jQuery(二)

    http://www.bubuko.com/infodetail-1438296.html 处理完毕需要整理贴进来 Python之路[第十三篇]jQuery案例-Form表单&插件及扩展   ...

  8. Python开发【第九篇】:HTML (二)

    python[第十四篇]HTML基础 时间:2016-08-08 20:57:27      阅读:49      评论:0      收藏:0      [点我收藏+] 标签: 什么是HTML? H ...

  9. [转载] Fiddler为所欲为第二篇 像OD一样调试 [二]

    首先,如果大家没有看过第一篇,可以先看看第一篇,了解Fiddler script的脚本哦.传送门:https://www.52pojie.cn/thread-854434-1-1.html 导语:其实 ...

随机推荐

  1. Container容器控件的使用、Hbox与Vbox布局管理器的使用、以及AjaxAction前后台事件响应

    1.由于有前后台交互功能,需要在Spring上下文中注册一个用于提供服务的bean,对于这个bean使用Spring提供的@Component标注,如果需要使用@Component注解,需要在项目中W ...

  2. 学习C++ Primer 的个人理解(二)

    本身就一定基础的读者我想变量常量这些概念应该已经不是问题了.但是本章还是有几个重点,需要特别留意一下的: 1.初始化和赋值是不同的操作 2.任何非0值都是true 3.使用新标准列表初始化,在有丢失精 ...

  3. mysql大数据高并发处理

    一.数据库结构的设计 如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,而且将会影响系统实际运行的性能.所以,在一个系统开始实施之前,完备的数据库模型的设计是必须的. ...

  4. 队列(链式存储)C++模板实现

    #include <iostream> using namespace std; //队列结点类 template <typename T> class QueueNode{ ...

  5. c#拖放

    AllowDrop DragEnter: if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Cop ...

  6. quality center的使用简介

    quality center是一个基于Web的测试管理工具,其实是伪B/S的软件,可以组织和管理应用程序测试流程的所有阶段,包括制定测试需求.计划测试.执行测试和跟踪缺陷.此外,通过Quality C ...

  7. WPF异步调用WCF服务

    wpf调用wcf时,第一次访问总耗时到达几秒,影响界面的用户体验,因此在wpf加载界面和加载数据时采用异步加载,即异步访问wcf服务, 由于是否采用异步加载和服务端无关,仅仅由客户端自己根据需要来选择 ...

  8. mysql索引使用笔记

    1.使用explain语句查看性能mysql> explain select product_id from orders where order_id in (123, 312, 223, 1 ...

  9. 用最直白的语言告诉你,hadoop是什么?

    hadoop应历史之潮流,随着理论探索.科学技术试验的不断开展,hadoop终于2006年问世,惊天地泣鬼神! hadoop雏形开始于2002年的Apache的Nutch,Nutch是一个开源Java ...

  10. E8.Net工作流平台开发篇

    E8.Net开发篇(一)   E8.Net开发框架有哪些源程序模型? E8.Net开发框架为开发企业流程应用系统提供了最佳实践的开发架构.范例及源代码,包括待办事项的组织.流程启动模型.处理模型.母版 ...