洛谷 [P3723] 礼物
2024-08-26 18:59:13
FFT
https://www.luogu.org/problemnew/solution/P3723
重点在于构造卷积的形式
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int MAXN = 400005;
const double PI = acos(-1);
int init() {
int rv = 0, fh = 1;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') fh = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
rv = (rv<<1) + (rv<<3) + c - '0';
c = getchar();
}
return fh * rv;
}
struct Complex {
double x, y;
Complex(double xx = 0.0, double yy = 0.0) {
x = xx; y = yy;
}
Complex operator + (const Complex &u) const {
return Complex(x + u.x, y + u.y);
}
Complex operator - (const Complex &u) const {
return Complex(x - u.x, y - u.y);
}
Complex operator * (const Complex &u) const {
return Complex(x * u.x - y * u.y, x * u.y + y * u.x);
}
}a[MAXN], b[MAXN];
int n, m, lim = 1, limcnt, rev[MAXN], num1[MAXN], num2[MAXN], ttt;
long long ans = 0, c;
void fft(Complex a[], int opt) {
for(int i = 0; i <= lim; i++) {
if(i < rev[i]) swap(a[i], a[rev[i]]);
}
for(int mid = 1; mid < lim; mid <<= 1) {
Complex wn = Complex(cos(PI / mid), opt * sin(PI / mid));
for(int R = mid << 1, j = 0; j < lim; j += R) {
Complex w = Complex(1.0, 0.0);
for(int k = 0; k < mid; k++) {
Complex x = a[j + k], y = w * a[j + mid + k];
a[j + k] = x + y;
a[j + mid + k] = x - y;
w = w * wn;
}
}
}
if(opt == -1) {
for(int i = 0; i <= lim; i++) {
a[i].x /= lim;
}
}
}
int main() {
n = init(); m = init();
for(int i = 1; i <= n; i++) {
num1[i] = init();
a[n - i].x = num1[i];
ans += num1[i] * num1[i];
ttt += num1[i];
}
for(int i = 0; i < n; i++) {
num2[i] = init();
b[i].x = b[i + n].x = num2[i];
ans += num2[i] * num2[i];
ttt -= num2[i];
}
double t = -(double)ttt / n;
if(t > 0.0) c = (int)(t + 0.5);
else c = (int) (t - 0.5);
ans += n * c * c + 2 * c * ttt;
while(lim <= n * 3) lim <<= 1, limcnt++;
for(int i = 0; i <= lim; i++)
rev[i] = (rev[i>>1]>>1) | ((i&1) << (limcnt - 1));
fft(a, 1); fft(b, 1);
for(int i = 0; i <= lim; i++) {
a[i] = a[i] * b[i];
}
fft(a, -1);
int tmp = 0;
for(int i = n - 1; i <= 2 * n - 1; i++) {
tmp = max(tmp, (int)(a[i].x + 0.01));
}
ans -= 2 * tmp;
cout << ans << endl;
return 0;
}
最新文章
- wpf 悬浮窗口的实现
- 如何学习JavaScript
- [Tool] 源代码管理之Git
- asp.net mvc 中的部分视图
- (七)STM32的RTC简单操作
- HBase入门
- ###《Effective STL》--Chapter2
- mybatis12 Usermapper.xml
- myeclipse8.6 for spring环境配置
- c++中vector使用
- JAVA web.xml中引用多个XML
- flink metric库的使用和自定义metric-reporter
- Codechef Bear and Clique Distances
- WebLogic使用总结(一)——WebLogic安装
- js let
- Python中进程线程协程小结
- Redis 分布式锁的实现
- LiveCharts文档-2FAQ
- 并查集 (Union-Find Sets)及其应用
- mybatis总结之一
热门文章
- 适配iOS10和Xcode8
- 【Django】Django中datetime的处理(strftime/strptime)
- OpenFaceswap 入门教程(3): 软件参数篇!
- 浅谈MapReduce工作机制
- Java课堂作业
- 基于django的个人博客网站建立(三)
- Python学习笔记:math模块(数学),random模块(随机数)
- The Moving Points - HDU - 4717 (模拟退火)
- CTU Open Contest 2017
- Codeforces Round #460 (Div. 2)-B. Perfect Number