UVALive_6886_Golf Bot(FFT快速傅里叶变换)
来源:互联网 发布:时时彩源码程序出售 编辑:程序博客网 时间:2024/03/28 18:22
传送门:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=77958#problem/C
题型:数论
题意:
集合A中取1个数或者2个数,其和变成一个新的集合S。q次查询,每次查询输入一个数,问q个数中有多少个数属于集合S。
集合A元素个数2e5,q<=2e5,A元素大小<=2e5,查询数字2e5
分析:
暴力枚举O(C(n,2)+n),O(n^2)复杂度过高。
FFT统计出现了哪些数,然后直接算结果就ok,复杂度O(nlogn)。
只取1个数只需要O(n)标记一下,S1 = {1,3,5}。
下面讨论取2个数的情况:
例如A = {1,3,5}
设多项式
则S2 = {2,4,6,8,10}
综上:S={1,2,3,4,5,6,8,10}
代码;
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define mt(a,b) memset(a,b,sizeof(a))using namespace std;const int M = 201000;struct Complex { double x,y; Complex(double _x=0,double _y=0) { x=_x; y=_y; } friend Complex operator -(const Complex &a,const Complex &b) { return Complex(a.x-b.x,a.y-b.y); } friend Complex operator +(const Complex &a,const Complex &b) { return Complex(a.x+b.x,a.y+b.y); } friend Complex operator *(const Complex &a,const Complex &b) { return Complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x); }};class FFT { Complex u,t; void change(Complex y[],int len) { for(int i=1,j=len>>1,k; i<len-1; i++) { if(i<j) swap(y[i],y[j]); k=len>>1; while(j>=k) { j-=k; k>>=1; } if(j<k) j+=k; } }public: void fft(Complex y[],int len,int on) { change(y,len); double tmp=-on*2*acos(-1.0); for(int h=2; h<=len; h<<=1) { Complex wn(cos(tmp/h),sin(tmp/h)); for(int j=0; j<len; j+=h) { Complex w(1,0); int h2=h>>1; for(int k=j; k<j+h2; k++) { u=y[k]; t=w*y[k+h2]; y[k]=u+t; y[k+h2]=u-t; w=w*wn; } } } if(on==-1) { for(int i=0; i<len; i++) { y[i].x/=len; } } }} g;int flag[M*4];Complex x[M*4];int a[M*2];int main() { int n,q; while(~scanf("%d",&n)) { mt(flag,0); int maxn = 0; for(int i=0; i<n; i++) { scanf("%d",&a[i]); flag[a[i]] = 1; maxn = max(maxn,a[i]); } int len = 1; maxn<<=1; while(len<maxn) len<<=1; for(int i=0; i<len; i++) { x[i] = Complex(flag[i],0); } g.fft(x,len,1); for(int i=0;i<len;i++){ x[i] = x[i]*x[i]; } g.fft(x,len,-1); mt(flag,0); for(int i=0;i<n;i++){ flag[a[i]]++; } for(int i=0;i<len;i++){ flag[i] += (int)(x[i].x+0.5); }// for(int i=0;i<len;i++){// printf("%d--->%d\n",i,flag[i]);// } scanf("%d",&q); int b; int ans = 0; while(q--){ scanf("%d",&b); if(flag[b]) ans++; } printf("%d\n",ans); } return 0;}/**31356245789*/
0 0
- UVALive_6886_Golf Bot(FFT快速傅里叶变换)
- 快速傅里叶变换(FFT)(ZZ)
- FFT快速傅里叶变换;
- 快速傅里叶变换(FFT)
- 关于FFT快速傅里叶变换
- FFT快速傅里叶变换
- FFT - 快速傅里叶变换
- 快速傅里叶变换(FFT)
- 快速傅里叶变换(FFT)
- GSL快速傅里叶变换FFT
- 快速傅里叶变换FFT
- 【数学】快速傅里叶变换(FFT)
- FFT 快速傅里叶变换 初探
- 快速傅里叶变换(FFT)
- [快速傅里叶变换--FFT]
- [FFT]快速傅里叶变换
- 快速傅里叶变换(FFT)
- 快速傅里叶变换(FFT)
- Asp.Net 详解IIS内部运行原理
- 百度面试相关问题
- string实现和使用说明
- JavaScript 运行机制详解:Event Loop
- Java 习惯用法总结
- UVALive_6886_Golf Bot(FFT快速傅里叶变换)
- Docker常用命令
- LeetCode——Minimum Depth of Binary Tree
- bower解决js的依赖管理
- PATBasic——1004. 成绩排名 (20)
- Windows7集成SP1微软原版光盘镜像下载大全
- 第16周项目1异常处理求平方根
- 搜狗语音云开发入门--移动端轻松添加高大上的语音识别
- 织梦后台文章发布时间为1970