hihocoder 1388 Periodic Signal FFT
来源:互联网 发布:sql union order by 编辑:程序博客网 时间:2024/05/01 15:39
http://hihocoder.com/problemset/problem/1388?sid=893835
呀,我的第一道fft
FFT是什么窝真的不太懂、、、
卷积窝也不懂
关于多项式乘法
首先把系数表达 转换为 点值表达,需要nlogn时间
然后点值表达计算,就可以O(n)完成
因此算法可以把时间降到nlogn
可以看到 卷积套路如上图:
而本题要求的是
显然前面平方和是固定的,就是要最大化最后的
然而这不符合卷积套路,但是我们可以发现这是个 【循环的乘积和】
如果我们套路地把B数组逆序一下,还是让原来相乘的那些数继续相乘。
于是下标就变成了
我们发现和卷积的 形式,还略有不同。
稍作分析:
因此,我们先把B逆序后的式子展开 ,然后把A、B数组添零扩充为两倍,原题所要求的
其实就相当于 A正序,B逆序、扩充2倍之后,的多项式乘法,对应的C[ n-k ] + C[ 2*n-k ]
因此,我们只需要把B数组逆序,然后把数组都扩充一倍,并填充0,然后跑FFT
就可以取max 得到答案了。
这里由于FFT精度不够,用的是NTT
700ms+
#include <bits/stdc++.h>using namespace std ;typedef long long ll ;const int maxn = 131072 ;+// const ll mod = ( 1ll << 47 ) * 7 * 4451 + 1 ; const ll mod = ( 1ll << 47 ) * 7 * 4451 + 1 ;const ll g = 3 ;struct Node{ ll x, y ; Node(ll a=0,ll b=0) { x=a,y=b; }} ; ll mul ( ll x, ll y ){ return ( x * y - ( long long ) ( x / ( long double ) mod * y + 1e-3 ) * mod + mod ) % mod ;}ll power ( ll a, ll b ){ ll res = 1, tmp = a ; while ( b ) { if ( b & 1 ) res = mul ( res, tmp ) ; tmp = mul ( tmp, tmp ) ; b >>= 1 ; } return res ;}void DFT ( ll y[], int n, bool rev ){ for ( int i = 1, j, t, k ; i < n ; ++ i ) { for ( k = n >> 1, t = i, j = 0 ; k ; k >>= 1, t >>= 1 ) { j = j << 1 | t & 1 ; } if ( i < j ) swap ( y[i], y[j] ) ; } for ( int s = 2, ds = 1 ; s <= n ; ds = s, s <<= 1 ) { ll wn = power ( g, ( mod - 1 ) / s ) ; if ( !rev ) wn = power ( wn, mod - 2 ) ; for ( int k = 0 ; k < n ; k += s ) { ll w = 1, t ; for ( int i = k ; i < k + ds ; ++ i, w = mul ( w, wn ) ) { y[i + ds] = ( y[i] - ( t = mul ( y[i + ds], w ) ) + mod ) % mod ; y[i] = ( y[i] + t ) % mod ; } } }}void FFT ( ll x1[], ll x2[], int n ){ DFT ( x1, n, 1 ) ; DFT ( x2, n, 1 ) ; for ( int i = 0 ; i < n ; ++ i ) x1[i] = mul ( x1[i], x2[i] ) ; DFT ( x1, n, 0 ) ; ll vn = power ( n, mod - 2 ) ; for ( int i = 0 ; i < n ; ++ i ) x1[i] = mul ( x1[i], vn ) ;}ll x1[maxn],x2[maxn];ll s1[maxn],s2[maxn];int main(){ int t; cin>>t; while(t--) { int n,i,j,k; cin>>n; ll len1,len2,len=1,ans=0; len1=len2=n; for (int i=0; i<n; i++)scanf("%lld",&s1[i]),ans+=s1[i]*s1[i]; // for (int i=n; i<2*n; i++) s1[i]=s1[i-n]; for (int i=0; i<n; i++)scanf("%lld",&s2[n-i-1]),ans+=s2[n-i-1]*s2[n-i-1]; //两个多项式长n,m,那么乘积长n+m-1, //这里求最接近且大于n+m-1的2^k,方便二叉树形式的运用吧 while(len<len1*2)len<<=1; for(i=0; i<len1; i++) x1[i]=s1[len1-1-i]; for(i=len1; i<len; i++) x1[i]=0; for(i=0; i<len2; i++) x2[i]=s2[len2-1-i]; for(i=len2; i<len; i++) x2[i]=0; FFT(x1,x2,len);//FFT转换成单位根形式 ll maxx=0; for (int i=n; i<len; i++) maxx=max(maxx,(long long )(x1[i-n]+x1[i])); printf("%lld\n",ans-2*maxx); } return 0;}
0 0
- hihocoder 1388 Periodic Signal FFT
- HihoCoder 1388 Periodic Signal 循环卷积(FFT)
- hihocoder 1388 Periodic Signal
- hiho 1388 Periodic Signal FFT
- 【hihoCoder #1388】【2016 acm 北京网络赛 F题】【FFT】 Periodic Signal
- hihocoder 1388 2016北京网络赛1006 Periodic Signal(卡精度的FFT)
- hihocoder 1388 2016北京网络赛1006 Periodic Signal(卡精度的FFT)
- HihoCoder1388(Periodic Signal)-fft(快速傅里叶变换)
- hihoCoder #1388 : Periodic Signal ( 2016 acm 北京网络赛 F题) _循环卷积
- Periodic Signal
- hihocoder-1388-高精度fft
- 2016ICPC北京站网络预选赛F hihoCoder1388 Periodic Signal,FFT|NTT+CRT
- hihocoder1388 Periodic Signal
- ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛 F. Periodic Signal(FFT 优化乘法)
- 【hihocoder 1388】 【NTT或者FFT 循环矩阵】
- Periodic Signal BeiJing 2016 区域赛
- 2016 ICPC 北京网络赛F题Periodic Signal,hiho1388 : Periodic Signal
- 北京网赛 F题 hiho1388 Periodic Signal
- 各类缓存设计、站点优化方案
- apache服务器设置禁用目录列表
- 文件的查找输出
- 如何做好产品运营?
- hdu2841 容斥
- hihocoder 1388 Periodic Signal FFT
- 关于以太网(Ethernet II)这个网络的个人理解以及应用(2)
- memcache、redis等常用nosql解决方案,优缺点以及使用场景
- 项目早期,运营该做什么?
- “兼容与传承----刘子舆绘画作品展” 在孔庙和国子监博物馆举办
- 旅游
- Odoo的Domain (一)
- 刷刷笔试题~~--[有关DFS的一些题]
- CVPR2016 论文快讯:人脸专题