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. java之线程(线程的创建方式、java中的Thread类、线程的同步、线程的生命周期、线程之间的通信)

    CPU:10核 主频100MHz 1核  主频    3GHz 那么哪一个CPU比较好呢? CPU核不是越多越好吗?并不一定.主频用于衡量GPU处理速度的快慢,举个例子10头牛运送货物快还是1架飞机运 ...

  2. netcore在CentOS7 下使用处理图片的问题

    请看代码,当你在centos下要把图片转为Base64的时候 MemoryStream ms = new MemoryStream(); try { Bitmap bmp = new Bitmap(f ...

  3. Nacos 安装(带视频)

    疯狂创客圈 Java 高并发[ 亿级流量聊天室实战]实战系列 [博客园总入口 ] 架构师成长+面试必备之 高并发基础书籍 [Netty Zookeeper Redis 高并发实战 ] 疯狂创客圈 高并 ...

  4. Kafka实战(七) - 优雅地部署 Kafka 集群

    既然是集群,必然有多个Kafka节点,只有单节点构成的Kafka伪集群只能用于日常测试,不可能满足线上生产需求. 真正的线上环境需要考量各种因素,结合自身的业务需求而制定.看一些考虑因素(以下顺序,可 ...

  5. Mysql、ES 数据同步

    数据同步中间件 不足:不支持 ES6.X 以上.Mysql 8.X 以上 ime 标识最大时间 logstash全量.增量同步解决方案 https://www.elastic.co/cn/downlo ...

  6. Password Management:Hardcoded Password 密码管理:硬编码密码

  7. Vultr主机绑定域名

    1.在腾讯云上注册域名 然后,域名实名认证 2.Vultr主机购买(看我之前写的:手把手教你如何自己搭梯子) 然后会获取到一个服务器IP地址 3.绑定域名与IP 点解,解析后会弹出让你输入IP地址,此 ...

  8. JDK性能分析工具-引用于深入理解JVM

    1.jps(JVM Process Status Tool) 列出正在运行的虚拟机进程. 2.jstat(JVM Statistics Monitoring Tool) 显示运行状态信息. 3.jin ...

  9. js-04-函数学习

    一.什么为函数? 函数是用来执行某些特定功能的代码,为了减少代码的重复使用,将函数作为代码使用,在需要时随时调用使用. 二.函数的声明(函数名严格区分大小写) 1.function命令 functio ...

  10. GPS定位的偏移校正(WGS84与火星坐标互转)

    地图坐标系目前包括: 地球坐标 (WGS84) WGS84:World Geodetic System 1984,是为GPS全球定位系统使用而建立的坐标系统. 国际标准,从 GPS 设备中取出的数据的 ...