Problem

Description

我的室友最近喜欢上了一个可爱的小女生。马上就要到她的生日了,他决定买一对情侣手环,一个留给自己,一个送给她。每个手环上各有 \(n\) 个装饰物,并且每个装饰物都有一定的亮度。

但是在她生日的前一天,我的室友突然发现他好像拿错了一个手环,而且已经没时间去更换它了!他只能使用一种特殊的方法,将其中一个手环中所有装饰物的亮度增加一个相同的整数 \(c\)(可能是负数)。并且由于这个手环是一个圆,可以以任意的角度旋转它,但是由于上面装饰物的方向是固定的,所以手环不能翻转。需要在经过亮度改造和旋转之后,使得两个手环的差异值最小。

在将两个手环旋转且装饰物对齐了之后,从对齐的某个位置开始逆时针方向对装饰物编号 \(1, 2,\cdots, n\),其中 \(n\) 为每个手环的装饰物个数,第一个手环的 \(i\) 号位置装饰物亮度为 \(x_i\),第二个手环的 \(i\) 号位置装饰物亮度为 \(y_i\),两个手环之间的差异值为(参见输入输出样例和样例解释):

\[\sum_{i = 1}^n (x_i - y_i)^2
\]

麻烦你帮他计算一下,进行调整(亮度改造和旋转),使得两个手环之间的差异值最小,这个最小值是多少呢?

Input Format

输入数据的第一行有两个数 \(n, m\),代表每条手环的装饰物的数量为 \(n\),每个装饰物的初始亮度小于等于 \(m\);

接下来两行,每行各有 \(n\) 个数,分别代表第一条手环和第二条手环上从某个位置开始逆时针方向上各装饰物的亮度。

Output Format

输出一个数,表示两个手环能产生的最小差异值。注意在将手环改造之后,装饰物的亮度可以大于 \(m\)。

Sample

Input

5 6
1 2 3 4 5
6 3 3 4 5

Output

1

Explanation

Explanation for Sample

需要将第一个手环的亮度增加 \(1\),第一个手环的亮度变为:\(2, 3, 4, 5, 6\)。旋转一下第二个手环,对于该样例,是将第二个手环的亮度 \(6, 3, 3, 4, 5\) 向左循环移动一个位置,使得第二手环的最终的亮度为:\(3, 3, 4, 5, 6\)。

此时两个手环的亮度差异值为 \(1\)。

Range

对于 \(30\%\) 的数据,\(n\le 500, m\le 10\);

对于 \(70\%\) 的数据,\(n\le 5000\);

对于 \(100\%\) 的数据,\(1\le n\le 50000, 1\le m\le 100, 1\le a_i\le m\)。

Algorithm

多项式

Mentality

由于加上的整数可以为负数,那么无论加在 \(x\) 还是 \(y\) 上没有本质差别。直接加在 \(x\) 上就好了。

那么对于式子:

\[\sum (x_i+c-y_i)^2
\]

我们可以拆开平方:

\[=\sum x_i^2+y_i^2+c^2+2x_ic-2y_ic-2x_iy_i\\
=\sum x_i^2+\sum y_i^2+nc^2+2(\sum x_i-\sum y_i)c-2\sum x_iy_i
\]

好的,前面两项都是定值。对于带 \(c\) 的项,由于其他系数皆为定值,就是一个普通的二次函数,直接找顶点即可最小。

那么我们只需要令 \(\sum x_iy_i\) 最大即可。考虑将 \(x\) 数组的下标翻转,则得到 \(\sum x_{n-i+1}*y_i\) 。

那么将 \(x\) 数组复制加倍,直接 \(FFT\) 将 \(x,y\) 乘起来,第 \(n+1\sim 2n\) 项就是 \(n\) 种旋转方法的结果,直接取 \(max\) 即可。

Code

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
using namespace std;
long long read() {
long long x = 0, w = 1;
char ch = getchar();
while (!isdigit(ch)) w = ch == '-' ? -1 : 1, ch = getchar();
while (isdigit(ch)) {
x = (x << 3) + (x << 1) + ch - '0';
ch = getchar();
}
return x * w;
}
#define cp complex<double>
const int Max_n = 5e5 + 5;
const double pi = acos(-1);
int n, m, ans;
int sx, sy, Max, mid, x[Max_n], y[Max_n];
int lim = 1, bit, rev[Max_n];
cp f[Max_n], g[Max_n];
void dft(cp *f, int t) {
for (int i = 0; i < lim; i++)
if (rev[i] > i) swap(f[i], f[rev[i]]);
for (int len = 1; len < lim; len <<= 1) {
cp Wn(cos(t * pi / len), sin(t * pi / len));
for (int i = 0; i < lim; i += len << 1) {
cp Wnk(1, 0);
for (int k = i; k < i + len; k++) {
cp a = f[k], b = Wnk * f[k + len];
f[k] = a + b, f[k + len] = a - b;
Wnk *= Wn;
}
}
}
}
void FFT() {
dft(f, 1), dft(g, 1);
for (int i = 0; i < lim; i++) f[i] *= g[i];
dft(f, -1);
for (int i = 0; i < lim; i++) f[i] /= lim;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("3723.in", "r", stdin);
freopen("3723.out", "w", stdout);
#endif
n = read(), m = read();
for (int i = 0; i < n; i++) {
f[i] = x[i] = read();
sx += x[i], ans += x[i] * x[i];
}
for (int i = 0; i < n; i++) {
g[i] = y[i] = read();
sy += y[i], ans += y[i] * y[i];
}
reverse(f, f + n);
for (int i = 0; i < n; i++) f[i + n] = f[i];
while (lim <= n * 3) bit++, lim <<= 1;
for (int i = 0; i < lim; i++)
rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (bit - 1));
FFT();
for (int i = n; i < 2 * n; i++) Max = max(Max, (int)(f[i].real() + 0.5));
double tp = double(sy - sx) / n;
mid = (int)(tp += tp < 0 ? -0.5 : 0.5);
cout << (ans += n * mid * mid + 2 * (sx - sy) * mid - 2 * Max);
}

【HNOI 2017】礼物的更多相关文章

  1. [HNOI 2017]礼物

    Description 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手 环,一个留给自己,一个送给她.每个手环上各有 n 个装饰物,并且每个装饰物都有一定的亮度.但是在 ...

  2. AH/HNOI 2017 礼物

    题目链接 描述 两个序列 \(x, y\),可以将一个序列每个值同时加非负整数 \(c\),其中一个序列可以循环移位,要求最小化: \[\sum_{i = 1}^{n}(x_i - y_i) ^ 2 ...

  3. [HNOI 2017]单旋

    Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据 结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的 ...

  4. [HNOI 2017]抛硬币

    Description 题库链接 两人抛硬币一人 \(a\) 次,一人 \(b\) 次.记正面朝上多的为胜.问抛出 \(a\) 次的人胜出的方案数. \(1\le a,b\le 10^{15},b\l ...

  5. [HNOI 2017]影魔

    Description 题库链接 给你一段长度为 \(n\) 的序列 \(K\) . \(m\) 组询问,每次给定左右端点 \(l,r\) .求出满足区间内下述贡献和. 如果一个区间的两个端点是这一个 ...

  6. 【HNOI 2017】大佬

    Problem Description 人们总是难免会碰到大佬.他们趾高气昂地谈论凡人不能理解的算法和数据结构,走到任何一个地方,大佬的气场就能让周围的人吓得瑟瑟发抖,不敢言语.你作为一个 OIer, ...

  7. 【HNOI 2017】影魔

    Problem Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还 ...

  8. HNOI 2017

    题目链接 我还是按bzoj AC数量排序做的 4827 这个其实如果推一下(求每个值)式子会发现是个卷积,然后FFT就好了 4826 记不太清了,可以求出每个点左右第一个比他的的点的位置,将点对看成平 ...

  9. [HNOI 2017]大佬

    Description 题库链接 题意简述来自Gypsophila. 你现在要怼 \(m\) 个大佬,第 \(i\) 个大佬的自信值是 \(C_i\) .每次怼大佬之前,你的自信值是 \(mc\),等 ...

随机推荐

  1. NPOI 工作簿一般设置

    HSSFWorkbook workbook = new HSSFWorkbook(); //声明一个空白的工作簿,也可以将已有文件转化为文件流作为参数声明一个工作簿,这样这个工作簿里就会有已有文件中的 ...

  2. php 弱类型总结

    0x01 前言 最近CTF比赛,不止一次的出了php弱类型的题目,借此想总结一下关于php弱类型以及绕过方式 0x02 知识介绍 php中有两种比较的符号 == 与 === <?php $a = ...

  3. Linux-3.14.12内存管理笔记【伙伴管理算法(4)】

    此处承接前面未深入分析的页面释放部分,主要详细分析伙伴管理算法中页面释放的实现.页面释放的函数入口是__free_page(),其实则是一个宏定义. 具体实现: [file:/include/linu ...

  4. Mac上打开终端的7种简单方法

    终端机是用于给Mac命令的便捷工具,尽管它可能会吓倒许多人.毕竟,这不像输入句子然后Mac响应那样简单.如果您有兴趣学习使用Terminal或只想输入一两个命令,我们在下面列出了一些文章,可以帮助您使 ...

  5. 集合系列 Map(十二):HashMap

    HashMap 是 Map 基于哈希散列算法的实现,其在 JDK1.7 中采用了数组+链表的数据结构.在 JDK1.8 中为了提高查询效率,采用了数组+链表+红黑树的数据结构.本文所有讲解均基于 JD ...

  6. CSS字体属性 font属性

    CSS的所有字体属性: ·-·  font 在一个声明中设置所有的字体属性 ·-·  font-family 指定文本的字体系列 ·-·  font-size 指定文本的字体大小  (属性值是整数字, ...

  7. Git实战指南----跟着haibiscuit学Git(第十篇)

    笔名:  haibiscuit 博客园: https://www.cnblogs.com/haibiscuit/ Git地址: https://github.com/haibiscuit?tab=re ...

  8. iPhone 启动页尺寸

    iPhone 启动页尺寸 4 640*960 5 640*1136 6 750*1334 6p 1242*2208

  9. 使用 Anydesk 5.1 TCP 通道(端口映射)功能从外网方便访问内网的 web/数据库等资源

    Anydesk 5.1 带来一个新的功能:TCP 通道,在家办公时,通过互联网进行远程桌面连接到公司电脑,可以将家用电脑的某个端口,映射到公司网络的某个电脑( IP + 端口),不局限于被远程桌面连接 ...

  10. apache storm基本原理及使用总结

    什么是Apache Storm Apache Storm是一个分布式实时大数据处理系统.Storm设计用于在容错和水平可扩展方法中处理大量数据.它是一个流数据框架,具有最高的摄取率.虽然Storm是无 ...