BZOJ 4827: [Hnoi2017]礼物(FFT)
来源:互联网 发布:linux 内核 usleep 编辑:程序博客网 时间:2024/05/29 06:45
题目传送门
轻轻戳我
Solution
题目欲求
先处理
由于那些
然后
原问题理所当然地变成了求
前面一堆常量,预处理搞出。最后那项把
但由于可以旋转,所以其实要求的是循环卷积。
有一个普通的类似破环为链的作法:我们发现如果将
于是:
只用求最后那项,直接将
由于
对于旋转的处理,还有一种神奇的方法:
把两个序列画出来,发现如果旋转一定位置的话,那么答案就是两个序列前
那么只要正着反着分别做一次
Code
#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <iostream>#include <cmath>#define MAXN 100010#define oo 0x7fffffffusing namespace std;const double PI = acos(-1.0);int n, m, nn, X[MAXN], Y[MAXN], P[MAXN], sumX, sumY, sum, C, ans;struct Complex{ double real, image; Complex() {} Complex(double _real, double _image){real = _real, image = _image;} friend Complex operator + (Complex A, Complex B){return Complex(A.real + B.real, A.image + B.image);} friend Complex operator - (Complex A, Complex B){return Complex(A.real - B.real, A.image - B.image);} friend Complex operator * (Complex A, Complex B){return Complex(A.real * B.real - A.image * B.image, A.real * B.image + A.image * B.real);}}a[MAXN<<2], b[MAXN<<2], c[MAXN<<2];void Get_P(){ for(int i = 1, t = 1; i < MAXN; i++) P[i] = (t < i) ? (t <<= 1) : t;}void Reverse(Complex *A){ for(int i = 0; i < nn-1; i++){ int j = 0; for(int k = 1, tmp = i; k < nn; k <<= 1, tmp >>= 1) j = ((j << 1) | (tmp & 1)); if(i < j) swap(A[i], A[j]); }}void FFT(Complex *A, int DFT){ Reverse(A); for(int s = 1; (1<<s) <= nn; s++){ int m = 1 << s; Complex wm = Complex(cos(DFT*2*PI/m), sin(DFT*2*PI/m)); for(int k = 0; k < nn; k += m){ Complex w = Complex(1, 0); for(int j = 0; j < (m>>1); j++){ Complex u = A[k+j], t = w * A[k+j+(m>>1)]; A[k+j] = u + t; A[k+j+(m>>1)] = u - t; w = w * wm; } } } if(!(~DFT)) for(int i = 0; i < nn; i++) A[i].real /= nn;}int main(){ freopen("bzoj4827.in", "r", stdin); freopen("bzoj4827.out", "w", stdout); Get_P(); scanf("%d%d", &n, &m); nn = P[n<<1] << 1; for(int i = 0; i < n; i++) scanf("%d", &X[i]), sumX += X[i]; for(int i = 0; i < n; i++) scanf("%d", &Y[i]), sumY += Y[i]; C = (sumY - sumX) / n; int Val1 = n * C * C + 2 * (sumX - sumY) * C; int Val2 = n * (C+1) * (C+1) + 2 * (sumX - sumY) * (C+1); if(Val1 > Val2) C ++; if(C > 0) for(int i = 0; i < n; i++) X[i] += C; else for(int i = 0; i < n; i++) Y[i] += C; for(int i = 0; i < n; i++) sum += X[i] * X[i], a[i] = a[i+n] = Complex(X[i], 0); for(int i = 0; i < n; i++) sum += Y[i] * Y[i], b[i] = Complex(Y[n-i-1], 0); for(int i = n<<1; i < nn; i++) a[i] = Complex(0, 0); for(int i = n; i < nn; i++) b[i] = Complex(0, 0); FFT(a, 1); FFT(b, 1); for(int i = 0; i < nn; i++) c[i] = a[i] * b[i]; FFT(c, -1); ans = oo; for(int i = n-1; i < (n<<1); i++) ans = min(ans, sum - 2 * (int)(c[i].real+.5)); printf("%d\n", ans); return 0;}
阅读全文
1 0
- bzoj 4827: [Hnoi2017]礼物 fft
- [FFT] BZOJ 4827 [Hnoi2017]礼物
- BZOJ 4827: [Hnoi2017]礼物(FFT)
- BZOJ 4827: [Hnoi2017]礼物 FFT
- bzoj 4827: [Hnoi2017]礼物 (FFT)
- bzoj 4827 [Hnoi2017]礼物(FFT)
- BZOJ 4827 [Hnoi2017]礼物
- bzoj 4827 [Hnoi2017]礼物
- [BZOJ4827][Hnoi2017]礼物-FFT
- bzoj 4827 礼物(fft)
- BZOJ4827: [Hnoi2017]礼物(FFT)
- [BZOJ4827][HNOI2017]礼物(FFT)
- BZOJ4827:[Hnoi2017]礼物 (FFT)
- 洛谷 P3723 [AH/HNOI2017]礼物(bzoj P4827 [Hnoi2017]礼物)
- 4827: [Hnoi2017]礼物
- HNOI2017 礼物
- 【AH/HNOI 2017】【BZOJ 4827】 礼物 (FFT,卷积,数学)
- BZOJ4827 [Hnoi2017]礼物
- 求数组中第n大(小)的元素
- ForeSpider数据采集系统脚本的几个小方法
- 反向传播算法
- [Python]使用Selenium的webdriver访问页面(Firefox的geckodriver)
- POJ 1426 Find The Multiple(BFS+同余模定理)
- BZOJ 4827: [Hnoi2017]礼物(FFT)
- B树和B+树 以及哈希索引
- 图片加载库-Fresco
- DWR第一篇之入门示例
- Python执行时间的计算方法
- 知识点--Java垃圾回收与内存分配策略
- 文字两侧加横线的解决方案 文字两侧加横线的需求你遇到过吗?在参与的项目中我遇到过这种需求,总结了一下,目前分为两种: 一,文字所在的背景是纯色,单一颜色; 二,文字所在背景是花色,或者是背景
- Oracle数据库知识梳理---续(子查询)
- 当反复开启同一个协程时,StopCoroutine可以停止这样开启的所有同名协程