bzoj 4827: [HNOI2017]礼物 (FFT)

一道FFT

然而据说暴力可以水70分

然而我省选的时候看到了直接吓傻了  连暴力都没打

太弱了啊QAQ

emmmm

详细的拆开就看其他题解吧233

最后那一步卷积其实我一直没明白

后来画画图终于懂了

只要把其中一个反过来

多项式乘法的结果中的每一项系数就对应某一个Σx[i] * y[j] 的结果

前面几项是不完全的结果

但是太小了就被忽略啦

代码如下

/**************************************************************
    Problem: 4827
    User: cminus
    Language: C++
    Result: Accepted
    Time:5644 ms
    Memory:24568 kb
****************************************************************/

#include <cstdio>
#include <cmath>
#include <complex>
using namespace std;

const int N = 500100;
typedef long long ll;
typedef complex<double> cp;
const double pi = acos(-1.0);
cp A[N], B[N];

void FFT(cp *y, int n, int type) {
    if (n == 1) return ;
    cp l[n >> 1], r[n >> 1];
    for (int i = 0; i <= n; i++)
        if (i & 1)  r[i >> 1] = y[i];
        else    l[i >> 1] = y[i];
    FFT(l, n >> 1, type); FFT(r, n >> 1, type);
    cp omegan(cos(2 * pi / n), sin(2 * pi * type / n)), omega(1, 0);
    for (int i = 0; i < n >> 1; i++) {
        y[i] = l[i] + r[i] * omega;
        y[i + (n >> 1)] = l[i] - r[i] * omega;
        omega *= omegan;
    }
}

int main() {
    int n, m, ans = 0, y = 0;
    scanf("%d %d", &n, &m);
    for (int i = 0; i < n; i++) {
        int x; scanf("%d", &x);
        A[n - i - 1] = x;
        ans += x * x;
    }
    for (int i = 0; i < n; i++) {
        int x; scanf("%d", &x);
        B[i] = x;
        ans += x * x;
        y += (int)B[i].real() - A[n - i - 1].real();
    }
    int n1;  for (n1 = 1; n1 <= n * 4; n1 <<= 1);
    for (int i = 0; i < n; i++)
        B[i + n] = B[i];
    FFT(A, n1, 1); FFT(B, n1, 1);
    for (int i = 0; i <= n1; i++)
        A[i] *= B[i];
    FFT(A, n1, -1);
    int temp = 0, z = (-y) / n;
    for (int i = 0; i < n; i++)  temp = max(temp, (int)(A[i + n - 1].real() / n1 + 0.5));
    ans -= temp * 2;
    temp = z * z * n + y * z * 2;
    z += 1; temp = min(temp, z * z * n + y * z * 2);
    z -= 2; temp = min(temp, z * z * n + y * z * 2);
// 有理有据的精度优化
    ans += temp;
    printf("%d\n", ans);
    return 0;
}
时间: 2024-08-10 21:29:37

bzoj 4827: [HNOI2017]礼物 (FFT)的相关文章

BZOJ 4827 [Hnoi2017]礼物 ——FFT

题目上要求一个循环卷积的最小值,直接破环成链然后FFT就可以了. 然后考虑计算的式子,可以分成两个部分分开计算. 前半部分FFT,后半部分扫一遍. #include <map> #include <ctime> #include <cmath> #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <alg

[BZOJ 4827][Hnoi2017]礼物(FFT)

Description 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手 环,一个留给自己,一 个送给她.每个手环上各有 n 个装饰物,并且每个装饰物都有一定的亮度.但是在她生日的前一天,我的室友突 然发现他好像拿错了一个手环,而且已经没时间去更换它了!他只能使用一种特殊的方法,将其中一个手环中所有 装饰物的亮度增加一个相同的自然数 c(即非负整数).并且由于这个手环是一个圆,可以以任意的角度旋转它, 但是由于上面 装饰物的方向是固定的,所以手环不能翻转.需要在经过

【bzoj4827】[Hnoi2017]礼物 FFT

题目描述 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手 环,一个留给自己,一 个送给她.每个手环上各有 n 个装饰物,并且每个装饰物都有一定的亮度.但是在她生日的前一天,我的室友突 然发现他好像拿错了一个手环,而且已经没时间去更换它了!他只能使用一种特殊的方法,将其中一个手环中所有 装饰物的亮度增加一个相同的自然数 c(即非负整数).并且由于这个手环是一个圆,可以以任意的角度旋转它, 但是由于上面 装饰物的方向是固定的,所以手环不能翻转.需要在经过亮度改造和旋转

BZOJ4827: [Hnoi2017]礼物

4827: [Hnoi2017]礼物 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 474  Solved: 334[Submit][Status][Discuss] Description 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手 环,一个留给自己,一 个送给她.每个手环上各有 n 个装饰物,并且每个装饰物都有一定的亮度.但是在她生日的前一天,我的室友突 然发现他好像拿错了一个手环,而且已经没时间去更换它了

bzoj 4827 礼物

bzoj 4827 礼物 可以看做将其中一个数列(假定为 \(a\) )都加上 \(c\) , \(c\) 可以为负数.易知这里 \(-m\leq c\leq m\). 记要求的答案为 \(ans\) , 大力拆开括号可得: \[ ans=\sum{(a_i+c-b_i)^2}\\=\sum a_i^2+\sum b_i^2+n\cdot c^2+2c\cdot (\sum a_i-\sum b_i)-2\sum a_i b_i. \] 这里的 \(a,b\) 是原数列元素不变,通过旋转得到的.

BZOJ4827 [Hnoi2017]礼物 多项式 FFT

原文链接http://www.cnblogs.com/zhouzhendong/p/8823962.html 题目传送门 - BZOJ4827 题意 有两个长为$n$的序列$x$和$y$,序列$x,y$的第$i$项分别是$x_i,y_i$. 选择一个序列$A$,现在你可以对它进行如下两种操作: $1.$ 得到一个和$A$循环同构的序列$A'$. $2.$ 给所有的$A'_i$都加上$c(c\in N^+)$,得到序列$A''$. 你进行上面两个操作之后,得到的序列分别为$x'',y''$(注意$

[AHOI2017/HNOI2017][bzoj4827] 礼物 [FFT]

题面 传送门 思路 首先,有一个结论:两个手环增加非负整数亮度,等于其中一个增加一个整数亮度(可以为负) 我们令增加量为$x$,旋转以后的原数列为${a}{b}$那么现在的费用就是: $\sum_{i=1}^n\left(a_i+x-b_i\right)^2$ 我们把第i项拿出来拆开,得到: $\left(a_i+x-b_i\right)^2=a_i^2+b_i^2+x^2+2a_ix-2a_ib_i-2b_ix$ 那么原式变成了 $\sum_{i=1}^na_i^2+\sum_{i=1}^nb

[bzoj4827][Hnoi2017]礼物_FFT

礼物 bzoj-4827 Hnoi-2017 题目大意:给定两个长度为$n$的手环,第一个手环上的$n$个权值为$x_i$,第二个为$y_i$.现在我可以同时将所有的$x_i$同时加上自然数$c$.我也可以将第一个手环任意旋转.旋转后每一个$x$对应一个$y$,那么代价为$\sum\limits_{i=0}^{n-1} (x_i-y_i)^2$.求最小代价. 注释:$1\le n\le 10^5$,$0\le maxval \le 100$. 想法: 水题啊..... 推推式子,我们假设就加了$

HNOI2017礼物

礼物 这估计是最水,最无脑的一道题了 首先发现总和最接近时答案最小 发现答案就是\((\sum_{i=1}^{n}a[i]^2+b[i]^2)-2*max(\sum_{i=1}^{n}a[i]*b[i+j])(0<=j<=n-1)\) 前面随便算,主要是后面那个式子,其实就是两个数列错位相乘加起来最大值 把\(b\)反过来就变成\(\sum_{i=1}^{n}a[i]*b[n-i-j])(0<=j<=n-1)\),直接就多项式卷积,FFT一算就行了. // luogu-judger