题意:给定两个 \(n\) 元环,环上每个点有权值,分别为 \(x_i, y_i\)。定义两个环的差值为

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

可以旋转其中的一个环,或者将其中一个环的每种权值加上一个数。求最小化的差值。

Solution: 加数只需要加在一个上面即可(假设可以为负),那么差值可以写成

\[\sum_{i=0}^{n-1}{(x_i-y_{i+k}+c)^2}
\]

我们可以将差值定义为旋转位数\(k\)与加数\(c\)的函数,即 \(f(k,c)\) 。我们现在要找的就是二元函数的峰值。展开得

\[f(k,c)=\sum{x_i^2} + \sum{y_i^2} + nc^2 + 2c \sum{x_i} - 2c\sum{y_i} - 2 \sum{x_i y_{(i+k)\%n}}
\]

我们惊喜地发现没有交叉项,即

\[f(k,c) = g(k) + h(c)
\]

那么我们只需要分别最小化两部分即可。

考虑\(g(k)\),翻转序列\(x\),这是一个循环卷积的形式。我们可以将序列\(y\)扩增一倍来转化为线性卷积。那么此时

\[g(k) = \sum_{i=0}^{n-1}{x_{n-1-i} y_{i+k}}
\]

对应到多项式乘法上,找\(g(k)\)的最小值,即在幂次为 \([n-1,2n-1)\) 的项中找最大系数即可。

考虑\(h(c)\),由于\(m \leq 100\),暴力枚举即可。

  1. #include<bits/stdc++.h>
  2. #define pi acos(-1)
  3. using namespace std;
  4. struct poly {
  5. typedef complex<double> E;
  6. int n,m;
  7. vector <double> c;
  8. void read(int deg) {
  9. c.resize(deg+1);
  10. for(int i=0;i<=deg;i++) scanf("%lf",&c[i]);
  11. }
  12. void write() {
  13. for(int i=0;i<c.size();i++) printf("%lf ",c[i]);
  14. printf("\n");
  15. }
  16. void fft(E *a,int f,int *R){
  17. for(int i=0;i<n;i++)if(i<R[i])swap(a[i],a[R[i]]);
  18. for(int i=1;i<n;i<<=1){
  19. E wn(cos(pi/i),f*sin(pi/i));
  20. for(int p=i<<1,j=0;j<n;j+=p){
  21. E w(1,0);
  22. for(int k=0;k<i;k++,w*=wn){
  23. E x=a[j+k],y=w*a[j+k+i];
  24. a[j+k]=x+y;a[j+k+i]=x-y;
  25. }
  26. }
  27. }
  28. }
  29. void mul(vector<double> A, vector<double> B){
  30. int *R; E *a,*b; int L=0;
  31. int _s=(A.size()+B.size()+2)<<5;
  32. a=(E*)malloc(_s); b=(E*)malloc(_s); R=(int*)malloc(_s);
  33. memset(a,0,_s);memset(b,0,_s);memset(R,0,_s);
  34. n=A.size()-1; for(int i=0;i<=n;i++) a[i]=A[i];
  35. m=B.size()-1; for(int i=0;i<=m;i++) b[i]=B[i];
  36. m=n+m;for(n=1;n<=m;n<<=1)L++;
  37. for(int i=0;i<n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
  38. fft(a,1,R);fft(b,1,R);
  39. for(int i=0;i<=n;i++)a[i]=a[i]*b[i];
  40. fft(a,-1,R);
  41. c.resize(m+1);
  42. for(int i=0;i<=m;i++)c[i]=a[i].real()/n;
  43. free(a); free(b); free(R);
  44. }
  45. poly mul(poly pa,poly pb) {
  46. poly pc; pc.mul(pa.c,pb.c); return pc;
  47. }
  48. poly operator * (const poly &pb) {
  49. poly ret = mul(*this,pb); return ret;
  50. }
  51. poly operator *= (const poly &pb) {
  52. mul(this->c,pb.c); return *this;
  53. }
  54. };
  55. int n,m,a[100005],b[100005];
  56. int main() {
  57. ios::sync_with_stdio(false);
  58. cin>>n>>m;
  59. for(int i=0;i<n;i++) cin>>a[i];
  60. for(int i=0;i<n;i++) cin>>b[i];
  61. long long sx=0,sy=0;
  62. for(int i=0;i<n;i++) sx+=a[i],sy+=b[i];
  63. long long px=0,py=0;
  64. for(int i=0;i<n;i++) px+=a[i]*a[i],py+=b[i]*b[i];
  65. long long ans = 1e+9;
  66. for(int i=-100;i<=100;i++) {
  67. ans = min(ans, n*i*i+2*i*sx-2*i*sy);
  68. }
  69. ans += px + py;
  70. poly x,y;
  71. x.c.resize(n);
  72. for(int i=0;i<n;i++) x.c[i]=a[n-i-1];
  73. y.c.resize(2*n);
  74. for(int i=0;i<n;i++) y.c[i]=y.c[i+n]=b[i];
  75. poly z=x*y;
  76. long long mx=0;
  77. for(int i=0;i<n;i++) mx=max(mx,(long long)(z.c[n+i-1]+0.5));
  78. cout<<ans-2*mx<<endl;
  79. }

[HNOI2017] 礼物 - 多项式乘法FFT的更多相关文章

  1. 多项式乘法(FFT)学习笔记

    ------------------------------------------本文只探讨多项式乘法(FFT)在信息学中的应用如有错误或不明欢迎指出或提问,在此不胜感激 多项式 1.系数表示法  ...

  2. 【learning】多项式乘法&fft

    [吐槽] 以前一直觉得这个东西十分高端完全不会qwq 但是向lyy.yxq.yww.dtz等dalao们学习之后发现这个东西的代码实现其实极其简洁 于是趁着还没有忘记赶紧来写一篇博 (说起来这篇东西的 ...

  3. 洛谷.3803.[模板]多项式乘法(FFT)

    题目链接:洛谷.LOJ. FFT相关:快速傅里叶变换(FFT)详解.FFT总结.从多项式乘法到快速傅里叶变换. 5.4 又看了一遍,这个也不错. 2019.3.7 叕看了一遍,推荐这个. #inclu ...

  4. @总结 - 1@ 多项式乘法 —— FFT

    目录 @0 - 参考资料@ @1 - 一些概念@ @2 - 傅里叶正变换@ @3 - 傅里叶逆变换@ @4 - 迭代实现 FFT@ @5 - 参考代码实现@ @6 - 快速数论变换 NTT@ @7 - ...

  5. [uoj#34] [洛谷P3803] 多项式乘法(FFT)

    新技能--FFT. 可在 \(O(nlogn)\) 时间内完成多项式在系数表达与点值表达之间的转换. 其中最关键的一点便为单位复数根,有神奇的折半性质. 多项式乘法(即为卷积)的常见形式: \[ C_ ...

  6. BZOJ4827 [Hnoi2017]礼物 多项式 FFT

    原文链接http://www.cnblogs.com/zhouzhendong/p/8823962.html 题目传送门 - BZOJ4827 题意 有两个长为$n$的序列$x$和$y$,序列$x,y ...

  7. UOJ 34 多项式乘法 FFT 模板

    这是一道模板题. 给你两个多项式,请输出乘起来后的多项式. 输入格式 第一行两个整数 nn 和 mm,分别表示两个多项式的次数. 第二行 n+1n+1 个整数,表示第一个多项式的 00 到 nn 次项 ...

  8. 【Luogu3808】多项式乘法FFT(FFT)

    题目戳我 一道模板题 自己尝试证明了大部分... 剩下的还是没太证出来... 所以就是一个模板放在这里 以后再来补东西吧.... #include<iostream> #include&l ...

  9. 【模板】多项式乘法(FFT)

    题目描述 给定一个n次多项式F(x),和一个m次多项式G(x). 请求出F(x)和G(x)的卷积. 输入输出格式 输入格式: 第一行2个正整数n,m. 接下来一行n+1个数字,从低到高表示F(x)的系 ...

随机推荐

  1. YARN安装和使用

    简介 Yet Another Resource Negotiator ,负责整个集群资源的调度,和管理,支持多框架资源统一调度(HIVE spark flink) 开启yarn 安装hadoop,可以 ...

  2. C#中的异步编程--探索await与async关键字的奥妙之处,原来理解和使用异步编程可以这么简单

    前言 await与async是C#5.0推出的新语法,关于await与async有很多文章讲解.但看完后有没有这样一种感觉,感觉这东西像是不错,但好像就是看不太懂,也不清楚该怎么使用.虽然偶有接触,但 ...

  3. XGBoost学习笔记1

    XGBoost XGBoost这个网红大杀器,似乎很好用,完事儿还是自己推导一遍吧,datacamp上面有辅助的课程,但是不太涉及原理 它究竟有多好用呢?我还没用过,先搞清楚原理,hahaha~ 参考 ...

  4. 【笔记】机器学习 - 李宏毅 - 6 - Logistic Regression

    Logistic Regression 逻辑回归 逻辑回归与线性回归有很多相似的地方.后面会做对比,先将逻辑回归函数可视化一下. 与其所对应的损失函数如下,并将求max转换为min,并转换为求指数形式 ...

  5. Wannafly Winter Camp 2020 Day 6G 单调栈 - 贪心

    对于排列 \(p\),它的单调栈 \(f\) 定义为,\(f_i\) 是以 \(p_i\) 结尾的最长上升子序列的长度 先给定 \(f\) 中一些位置的值,求字典序最小的 \(p\) 使得它满足这些值 ...

  6. Eclipse使用Alibaba Cloud Toolkit极速部署项目

    个人博客 地址:https://www.wenhaofan.com/a/20190716205809 什么是Alibaba Cloud Toolkit Cloud Toolkit 是针对 IDE 平台 ...

  7. 用JavaScript设计和创建对象

    通过在优锐课的java学习分享中,get很多学习新技能,分享给大家参考学习. 介绍 在阅读此分步指南之前,你可能需要关注面向对象编程的介绍. 以下步骤中包含的Java代码与该文章理论中使用的Book对 ...

  8. ng-模板语法

    插值 文本绑定 <p>Message: {{ msg }}</p> <p [innerHTML]="msg"></p> 属性绑定 & ...

  9. tensorflow张量排序

    本篇记录一下TensorFlow中张量的排序方法 tf.sort和tf.argsort # 声明tensor a是由1到5打乱顺序组成的 a = tf.random.shuffle(tf.range( ...

  10. JS阻止事件冒泡与浏览器默认行为

    阻止冒泡 W3C的方法是e.stopPropagation() IE是e.cancelBubble = true; 阻止默认行为 W3C的方法e.preventDefault(), IE是e.retu ...