题目链接:https://ac.nowcoder.com/acm/contest/881/C

题目大意

  给定 m 和 n 个整数 ai,$-m \leq a_i \leq m$,求$\sum\limits_{i = 1}^{n} (\frac{a_i}{m} - p_i)^2$在约束条件$\sum\limits_{i = 1}^{n} p_i = 1, p_i \geq 0$下的最小值。

分析

  首先,为了方便计算,可以把 p 坐标都扩大 m 倍,最后结果除个 m2 即可。
  如此一来只需要算$\sum\limits_{i = 1}^{n} (a_i - p_i)^2$即可。
  根据 AM-GM 不等式(算术—几何均值不等式)(这里先假设$p_i \geq a_i 或者 p_i \leq a_i$):

$$\begin{align*}
\frac{\sum\limits_{i = 1}^{n} (a_i - p_i)^2}{n} \geq \sqrt[n]{\prod\limits_{i = 1}^{n} (a_i - p_i)^2} \\
当且仅当 p_1 - a_1 = p_2 - a_2 = \dots = p_n - a_n 时取等号。
\end{align*}$$

  于是可以得到关于 pi 的式子:$n(p_i - a_i) = m - \sum\limits_{i = 1}^{n} a_i$。
  于是答案就显而易见了。
  但问题是,由于约束条件,pi 并不会都大于 0 且都大于 $a_i$ 或小于 $a_i$,为了解决这个问题,我们先把 ai 从大到小排个序,然后利用上面的 AM-GM 不等式。
  然后我们发现以某个数 k 为分界,$p_1 \dots p_k$ 都是大于等于 0 的,而 $p_{k + 1} \dots p_n$ 都是小于零的。
  于是我们可以让 $p_{k + 1} \dots p_n$ 全部取 0,然后在 $[1, k]$ 上递归运用 AM-GM 不等式,直到找到一个区间,没有 $p_i$ 小于 0,而这个时候一定有$p_i \geq a_i 或者 p_i \leq a_i$(迷)。(具体可用二分法实现)
  
  那有没有可能 $p_{k + 1} \dots p_n$ 中选几个取一个大于 0 的值,答案能更小呢?这个我不晓得,也不会证,不过代码AC了,说明是没可能的。
  我的理解是,与其给自己,不如均摊。
  

  然后这边有大佬的解释:https://blog.nowcoder.net/n/1539da6d6d6e47a6998b5c6f5bba2167?tdsourcetag=s_pcqq_aiomsg

  思想其实和我一样,大佬解释为推平,推到推不下去为止。

  

  正解用了拉格朗日乘子法,但是写的太飘,解释的又太少,有些符号又看不懂什么意思,思维太跳,反正我是看不懂。

代码如下

 #include <bits/stdc++.h>
using namespace std; #define INIT() ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define Rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define rFor(i,t,s) for (int i = (t); i >= (s); --i)
#define ForLL(i, s, t) for (LL i = LL(s); i <= LL(t); ++i)
#define rForLL(i, t, s) for (LL i = LL(t); i >= LL(s); --i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
#define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i) #define pr(x) cout << #x << " = " << x << " "
#define prln(x) cout << #x << " = " << x << endl #define LOWBIT(x) ((x)&(-x)) #define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define UNIQUE(x) x.erase(unique(x.begin(), x.end()), x.end())
#define REMOVE(x, c) x.erase(remove(x.begin(), x.end(), c), x.end()); // ?? x ?????? c
#define TOLOWER(x) transform(x.begin(), x.end(), x.begin(),::tolower);
#define TOUPPER(x) transform(x.begin(), x.end(), x.begin(),::toupper); #define ms0(a) memset(a,0,sizeof(a))
#define msI(a) memset(a,inf,sizeof(a))
#define msM(a) memset(a,-1,sizeof(a)) #define MP make_pair
#define PB push_back
#define ft first
#define sd second template<typename T1, typename T2>
istream &operator>>(istream &in, pair<T1, T2> &p) {
in >> p.first >> p.second;
return in;
} template<typename T>
istream &operator>>(istream &in, vector<T> &v) {
for (auto &x: v)
in >> x;
return in;
} template<typename T>
ostream &operator<<(ostream &out, vector<T> &v) {
Rep(i, v.size()) out << v[i] << " \n"[i == v.size()];
return out;
} template<typename T1, typename T2>
ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) {
out << "[" << p.first << ", " << p.second << "]" << "\n";
return out;
} inline int gc(){
static const int BUF = 1e7;
static char buf[BUF], *bg = buf + BUF, *ed = bg; if(bg == ed) fread(bg = buf, , BUF, stdin);
return *bg++;
} inline int ri(){
int x = , f = , c = gc();
for(; c<||c>; f = c=='-'?-:f, c=gc());
for(; c>&&c<; x = x* + c - , c=gc());
return x*f;
} template<class T>
inline string toString(T x) {
ostringstream sout;
sout << x;
return sout.str();
} inline int toInt(string s) {
int v;
istringstream sin(s);
sin >> v;
return v;
} //min <= aim <= max
template<typename T>
inline bool BETWEEN(const T aim, const T min, const T max) {
return min <= aim && aim <= max;
} typedef long long LL;
typedef unsigned long long uLL;
typedef pair< double, double > PDD;
typedef pair< int, int > PII;
typedef pair< int, PII > PIPII;
typedef pair< string, int > PSI;
typedef pair< int, PSI > PIPSI;
typedef set< int > SI;
typedef set< PII > SPII;
typedef vector< int > VI;
typedef vector< double > VD;
typedef vector< VI > VVI;
typedef vector< SI > VSI;
typedef vector< PII > VPII;
typedef map< int, int > MII;
typedef map< int, string > MIS;
typedef map< int, PII > MIPII;
typedef map< PII, int > MPIII;
typedef map< string, int > MSI;
typedef map< string, string > MSS;
typedef map< PII, string > MPIIS;
typedef map< PII, PII > MPIIPII;
typedef multimap< int, int > MMII;
typedef multimap< string, int > MMSI;
//typedef unordered_map< int, int > uMII;
typedef pair< LL, LL > PLL;
typedef vector< LL > VL;
typedef vector< VL > VVL;
typedef priority_queue< int > PQIMax;
typedef priority_queue< int, VI, greater< int > > PQIMin;
const double EPS = 1e-;
const LL inf = 0x7fffffff;
const LL infLL = 0x7fffffffffffffffLL;
const LL mod = 1e9 + ;
const int maxN = 1e4 + ;
const LL ONE = ;
const LL evenBits = 0xaaaaaaaaaaaaaaaa;
const LL oddBits = 0x5555555555555555; LL n, m, a[maxN], preSum[maxN], ans; int main(){
//freopen("MyOutput.txt","w",stdout);
//freopen("input.txt","r",stdin);
//INIT();
while(~scanf("%lld %lld", &n, &m)) {
For(i, , n) scanf("%lld", &a[i]);
sort(a + , a + n + , greater< LL >()); For(i, , n) preSum[i] = a[i] + preSum[i - ]; int l = , r = n;
while(l < r) {
int mid = (l + r) >> ; if(m - preSum[mid + ] + (mid + ) * a[mid + ] >= ) l = mid + ;
else r = mid;
}
ans = (m - preSum[l]) * (m - preSum[l]) * l;
For(i, l + , n) ans += a[i] * a[i] * l * l; LL x = m * m * l * l;
LL d = __gcd(ans, x);
ans /= d;
x /= d;
if(x == ) printf("%lld\n", ans);
else printf("%lld/%lld\n", ans, x);
}
return ;
}
/*
7 16
4 9 -4 -6 -3 5 13
469/1024 8 16
4 9 -4 -6 -3 5 13 7
79/128
*/

2019 牛客多校第一场 C Euclidean Distance ?的更多相关文章

  1. 2019牛客多校第一场 I Points Division(动态规划+线段树)

    2019牛客多校第一场 I Points Division(动态规划+线段树) 传送门:https://ac.nowcoder.com/acm/contest/881/I 题意: 给你n个点,每个点有 ...

  2. 2019牛客多校第一场E ABBA(DP)题解

    链接:https://ac.nowcoder.com/acm/contest/881/E 来源:牛客网 ABBA 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 524288K,其他语 ...

  3. 2019牛客多校第一场A-Equivalent Prefixes

    Equivalent Prefixes 传送门 解题思路 先用单调栈求出两个序列中每一个数左边第一个小于自己的数的下标, 存入a[], b[].然后按照1~n的顺序循环,比较 a[i]和b[i]是否相 ...

  4. 2019牛客多校第一场 A.Equivalent Prefixes

    题目描述 Two arrays u and v each with m distinct elements are called equivalent if and only if RMQ(u,l,r ...

  5. 2019 牛客多校第一场 D Parity of Tuples

    题目链接:https://ac.nowcoder.com/acm/contest/881/D 看此博客之前请先参阅吕凯飞的论文<集合幂级数的性质与应用及其快速算法>,论文中很多符号会被本文 ...

  6. 2019牛客多校第一场 E-ABBA(dp)

    ABBA 题目传送门 解题思路 用dp[i][j]来表示前i+j个字符中,有i个A和j个B的合法情况个数.我们可以让前n个A作为AB的A,因为如果我们用后面的A作为AB的A,我们一定也可以让前面的A对 ...

  7. 【2019牛客多校第一场】XOR

    题意: 给你一个集合A,里边有n个正整数,对于所有A的.满足集合内元素异或和为0的子集S,问你∑|S| n<=1e5,元素<=1e18 首先可以转化问题,不求∑|S|,而是求每个元素属于子 ...

  8. 2019 牛客多校第一场 B Integration

    题目链接:https://ac.nowcoder.com/acm/contest/881/B 题目大意 给定 n 个不同的正整数 ai,求$\frac{1}{\pi}\int_{0}^{\infty} ...

  9. 2019牛客多校第一场E ABBA 贪心 + DP

    题意:问有多少个有(n + m)个A和(n + m)个B的字符串可以凑出n个AB和m个BA. 思路:首先贪心的发现,如果从前往后扫,遇到了一个A,优先把它看成AB的A,B同理.这个贪心策略用邻项交换很 ...

随机推荐

  1. delphi 多线程编程

    开始本应该是一篇洋洋洒洒的文字, 不过我还是提倡先做起来, 在尝试中去理解.先试试这个: procedure TForm1.Button1Click(Sender: TObject); var i: ...

  2. Sqli labs系列-less-3 。。。

    原本想着找个搜索型的注入玩玩,毕竟昨天被实力嘲讽了 = = . 找了好长时间,我才发现,我没有 = = ,网上搜了一个存在搜索型注入的源码,我看了好长时间,楞没看出来从哪里搜索注入了....估计是我太 ...

  3. html+css判断各个IE浏览器版本

    html+css判断各个IE浏览器版本 在编写网页代码时,各种浏览器的兼容性是个必须考虑的问题,有些时候无法找到适合所有浏览器的写法,就只能写根据浏览器种类区别的代码,这时就要用到判断代码了. 在HT ...

  4. STM32库中自定义的数据类型

    在头文件 <stdint.h> 中 1 /* exact-width signed integer types */ typedef signed char int8_t; typedef ...

  5. CSS:CSS Display(显示) 与 Visibility(可见性)

    ylbtech-CSS:CSS Display(显示) 与 Visibility(可见性) 1.返回顶部 1. CSS Display(显示) 与 Visibility(可见性) display属性设 ...

  6. mongodb 数据修改

    update:语法格式如下: db.collection.update( <query>, <update>, { upsert: <boolean>, multi ...

  7. hql 跟 sql 区别

    hql 跟 sql 区别  1.hql与sql的区别 sql 面向数据库表查询 hql 面向对象查询 hql : from 后面跟的 类名+类对象 where 后 用对象的属性做条件 sql: fro ...

  8. <软件测试>软件测试

    1.软件测试基础 软件测试工程师:查找错误和缺陷,然后要求开发人员进行修改,保证软件质量. 漏洞(360安全漏洞):硬件,软件,协议的具体实现或系统安全策略存在缺陷,从而可以使攻击者在未授权的情况下破 ...

  9. C-Ubuntu中MySQL出现ERROR1698(28000):Access denied for user root@localhost错误解决方法

    卸载原先的MySQL,重新安装过程中没有提示设置密码, 当键入命令:mysql -uroot -p; 不知密码是什么,输入主机的密码以及不输入密码,回车后都出现标题错误. 寻找多篇相关博文,验证如下博 ...

  10. ida 符号路径设置

    cfg/pdf.cfg 文件中主要有两个字段 PDBSYM_DOWNLOAD_PATH 这个字段可以注释掉 PDBSYM_SYMPATH 这个字段需要设置一个符号路径,具体设置方法和WinDBG的设置 ...