题目链接

传送门

题意

给你\(n\)个数\(a_i\),要你在满足下面条件下使得\(\sum\limits_{i=1}^{n}(a_i-p_i)^2\)最小(题目给的\(m\)只是为了将\(a_i\)变成一个整数,那么我们就当此处的\(p_i\)扩大为题目给的\(m\)倍,然后把\(m\)放到分母去,以下不再解释):

  • \(p_i\in\mathbb{R}\);
  • \(p_i\geq 0,i\in[1,n]\);
  • \(\sum\limits_{i=1}^{n}p_i=m\)。

思路

由于叉姐的题解太高深了,本菜鸡完全看不懂(爆哭),因此我们从其他角度来求解本题。

首先根据题目要求的式子和条件可以发现我们能做的只是将\(p_i\)合理赋值使得\(\sum\limits_{i=1}^{n}(a_i-p_i)^2\)最小,且\(a_i\in[-m,m],p_i\in[0,m]\),那么\(p_i\)只能将\(a_i\)的值不断减小而不能增加(即使\(a_i<0\)),因此我们就可以通过调节\(p_i\)的值使得\(a_i\)的最大值尽可能的小,且\(\sum\limits_{i=1}^{n}p_i=m\)。

假设我们进行处理前\(i-1\)后\(p\)的和还剩下\(las\),前\(i\)个的\(a\)的值都已经被削到了\(a_i\),那么:

  • 如果\(i\times|(a[i+1]-a[i])|\leq las\),那么\(las=las-i\times|(a[i+1]-a[i])|\);
  • 否则,就记录这个位置为\(idx\),并且\(break\)(\(idx\)的初始值为\(n\))。

其中的\(idx\)就是说我们可以通过调节\(p_i\)的值使得前\(idx\)个数都相等且等于\(a_{idx}-\frac{las}{idx}\),因此最后答案是\(\frac{idx\times(a_{idx}-\frac{las}{idx})^2+\sum\limits_{i=idx+1}^{n}a_{idx}^2}{m^2}\)(因为我们最初始时将\(a_i,p_i\)都扩大了\(m\)倍,将\(m\)丢到了分母)。

如果没看懂我们可以通过分析样例\(3\)来帮助理解:

首先我们将\(a\)数组排序得到:

    \(3\)     \(1\)     \(-2\)

  • 处理前\(1\)个数,此时\(las=10>1\times|1-3|=2\),于是我们将\(a_1\)变成\(1\),\(las\)消耗\(2\);
  • 处理前\(2\)个数,此时\(las=8>2\times|-2-1|=6\),于是我们将\(a_1,a_2\)变成\(-2\),\(las\)消耗\(6\);
  • 处理前\(3\)个数,此时\(las=2,a_1=a_2=a_3=-2\),由于\(las\)最后要变成\(0\)且\(a_i\)的最大值要尽可能小,那么我们需要均匀分配,所以最后\(a_1=a_2=a_3=-2-\frac{2}{3}=-\frac{8}{3}\)。

所以最后答案为\(\frac{(-\frac{8}{3})^2\times 3}{10\times 10}=\frac{16}{75}\)。

\(update\):

证明这个写法的正确性:

假设现在有两个数\(a,b(a\geq b)\),总的可以减少的数量为\(m\)。

1.首先证明当\(a-b\geq m\)时全放在\(a\)上最优:

设\(m\)中有\(x(1\leq x\leq m)\)用在\(b\)上,那么和为\((a-m+x)^2+(b-x)^2\),全用在\(a\)上的话和为\((a-m)^2+b^2\),两者做差:

\[\begin{aligned}
&(a-m+x)^2+(b-x)^2-(a-m)^2-b^2&\\
=&(a-m)^2+2x(a-m)+x^2+b^2-2bx+x^2-(a-m)^2-b^2&\\
=&2x^2+2x(a-m)-2bx&\\
=&2x^2+2x(a-b-m)\geq 0&
\end{aligned}
\]

2.再证明当\(a=b,m\geq 0\)时均分最优:

设\(m\)中有\(x(1\leq x< \frac{m}{2})\)用在\(b\)上,那么和为\((a-m+x)^2+(b-x)^2\),将其化简:

\[\begin{aligned}
&(a-m+x)^2+(b-x)^2&\\
=&(a-m)^2+2(a-m)x+x^2+b^2-2bx+x^2&\\
=&(a-m)^2+b^2+2x^2+2(a-m-b)x&\\
=&(a-m)^2+b^2+2(x^2-mx)(\text{题目给定的}a=b)&
\end{aligned}
\]

由于前一半和\(x\)无关,而后一半\(x^2-mx=(x-\frac{m}{2})^2-\frac{m^2}{4}\)在\(x=\frac{m}{2}\)时取最小值。

最后我们来讨论有\(n\)个数分配\(m\),其中\(a,b\)分别为\(n\)个数中的最大和次大值时为什么当\(m>a-b\)时每次将最大值减小到次大值是最优的的情况:

  • \((1).\)首先如果将\(m\)全部减到一个数上,那么肯定是减小最大值是最优的:\((a-m)^2+c^2-a^2-(c-m)^2=a^2-2am+m^2+c^2-a^2-c^2+2cm-m^2=2m(c-a)<0(c\)为剩余\(n-1\)个数中的任意一个数);
  • \((2).\)如果分配到两个数上那么也一定时分到最大值和次大值上,理由同上;那么此时我们应该怎么分配最优呢?我们发现当\(a\)减少到\(a=b\)之后如果再减少\(a\)的话,\(b\)就已经大于\(a\)成为新的最大值了,那么再减小\(a\)肯定不是最优解(理由为\((1)\)),因此只能将最大值\(a\)减小到次大值\(b\),然后根据上面的\(2\)得知均匀分配最优;
  • 分配到任意多个数的情况基本和\((2)\)相同。

因此我们可以得知本题的解决策略是正确的。

(如果想法或者证明过程有错误,还请各位大佬指正~)

代码实现如下

#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("D://Code//in.txt","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-8;
const int mod = 1000000007;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL; int n, m;
int a[maxn]; int main() {
#ifndef ONLINE_JUDGE
FIN;
#endif // ONLINE_JUDGE
while(~scanf("%d%d", &n, &m)) {
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
sort(a + 1, a + n + 1, [](int a, int b){return a > b;});
int idx = n;
int las = m;
for(int i = 1; i < n; ++i) {
if(i * abs(a[i+1] - a[i]) > las) {
idx = i;
break;
} else {
las -= i * abs(a[i+1] - a[i]);
}
}
LL num1 = 1LL * (idx * a[idx] - las) * (idx * a[idx] - las);
LL num2 = 1LL * idx * m * m;
for(int i = idx + 1; i <= n; ++i) {
num1 += 1LL * a[i] * a[i] * idx;
}
LL tmp = __gcd(num1, num2);
num1 /= tmp, num2 /= tmp;
if(num2 == 1) printf("%lld\n", num1);
else printf("%lld/%lld\n", num1, num2);
}
return 0;
}

2019年牛客多校第一场 C题Euclidean Distance 暴力+数学的更多相关文章

  1. 2019年牛客多校第一场B题Integration 数学

    2019年牛客多校第一场B题 Integration 题意 给出一个公式,求值 思路 明显的化简公式题,公式是分母连乘形式,这个时候要想到拆分,那如何拆分母呢,自然是裂项,此时有很多项裂项,我们不妨从 ...

  2. 2019年牛客多校第一场 I题Points Division 线段树+DP

    题目链接 传送门 题意 给你\(n\)个点,每个点的坐标为\((x_i,y_i)\),有两个权值\(a_i,b_i\). 现在要你将它分成\(\mathbb{A},\mathbb{B}\)两部分,使得 ...

  3. 2019年牛客多校第一场 H题XOR 线性基

    题目链接 传送门 题意 求\(n\)个数中子集内所有数异或为\(0\)的子集大小之和. 思路 对于子集大小我们不好维护,因此我们可以转换思路变成求每个数的贡献. 首先我们将所有数的线性基的基底\(b\ ...

  4. 2019年牛客多校第一场 B题 Integration 数学

    题目链接 传送门 思路 首先我们对\(\int_{0}^{\infty}\frac{1}{\prod\limits_{i=1}^{n}(a_i^2+x^2)}dx\)进行裂项相消: \[ \begin ...

  5. 2019年牛客多校第一场 E题 ABBA DP

    题目链接 传送门 思路 首先我们知道\('A'\)在放了\(n\)个位置里面是没有约束的,\('B'\)在放了\(m\)个位置里面也是没有约束的,其他情况见下面情况讨论. \(dp[i][j]\)表示 ...

  6. Cutting Bamboos(2019年牛客多校第九场H题+二分+主席树)

    题目链接 传送门 题意 有\(n\)棵竹子,然后有\(q\)次操作,每次操作给你\(l,r,x,y\),表示对\([l,r]\)区间的竹子砍\(y\)次,每次砍伐的长度和相等(自己定砍伐的高度\(le ...

  7. 2019年牛客多校第二场 F题Partition problem 爆搜

    题目链接 传送门 题意 总共有\(2n\)个人,任意两个人之间会有一个竞争值\(w_{ij}\),现在要你将其平分成两堆,使得\(\sum\limits_{i=1,i\in\mathbb{A}}^{n ...

  8. MAZE(2019年牛客多校第二场E题+线段树+矩阵乘法)

    题目链接 传送门 题意 在一张\(n\times m\)的矩阵里面,你每次可以往左右和下三个方向移动(不能回到上一次所在的格子),\(1\)表示这个位置是墙,\(0\)为空地. 现在有\(q\)次操作 ...

  9. Kth Minimum Clique(2019年牛客多校第二场D题+k小团+bitset)

    目录 题目链接 题意 思路 代码 题目链接 传送门 题意 找第\(k\)小团. 思路 用\(bitset\)来标记每个结点与哪些结点直接有边,然后进行\(bfs\),在判断新加入的点与现在有的点是否都 ...

随机推荐

  1. 零基础C#网站开发实战教学(全套)最新更新2019-12-16。。。

    这是林枫山自己编写制作的全套Visual Studio 2013 C# 网站开发案例实战教学教程,欢迎下载学习. 下载目录链接如下(如果链接下载不了,请加QQ:714259796获取教程): 网站界面 ...

  2. Spring Boot启动时出现WARN:No MyBatis mapper was found in

    今天发现spring-boot继承mybatis启动时老是出现WARN: org.mybatis.spring.mapper.ClassPathMapperScanner - No MyBatis m ...

  3. Hadoop入门——初识Hadoop

    一.hadoop是什么 Hadoop被公认是一套行业大数据标准开源软件,在分布式环境下提供了海量数据的处理能力.几乎所有主流厂商都围绕Hadoop开发工具.开源软件.商业化工具和技术服务.今年大型IT ...

  4. Ant Design 学习记录

    遇到的问题: 点击列表中的一个字段 , 显示出一条指定id(其他筛选条件的)数据 解决这个问题之前,要先了解 Antd的 Table中的  Column  列描述数据对象,是 columns 中的一项 ...

  5. 解决IntelliJ IDEA 控制台输出中文乱码问题

    解决IntelliJ IDEA 控制台输出中文乱码问题 问题描述:如图,控制台输出的字符,乱码 解决方案 第一步:修改intellij idea配置文件: 找到Intellij idea安装目录,bi ...

  6. spring较为常用注解

    @Configuration 从Spring3.0,@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被Annotat ...

  7. TP3.2 日期默认格式

    <input type="text" id="create_time" name="create_time" required=&qu ...

  8. c++ pipe实现父子进程通信

    1.父子进程通信pipe编程流程 -创建管道 -设置进程的输出到管道 -创建进程 -关闭管道写句柄 -读管道读句柄,把数据读到一个buffer里 2.注意事项 -读管道数据的时候,一定要关闭写句柄: ...

  9. Go语言【学习】defer和逃逸分析

    defer 什么是defer? defer是Go语言的一中用于注册延迟调用的机制,使得函数活语句可以再当前函数执行完毕后执行 为什么需要defer? Go语言提供的语法糖,减少资源泄漏的发生 如何使用 ...

  10. springboot2.x 使用redis (入门)

    在使用之前先简单介绍一下,redis和mongoDB这两个nosql的区别以及使用场景. 1. redis redis是一个分布式缓存.高性能的key-value数据库.支持存储的value类型包括s ...