BZOJ4827 [Hnoi2017]礼物


Solution

如果一串数的增加,不就等于另一串数减吗?

那么我们可以把答案写成另一个形式:

\(ans=\sum_{i=1}^n(x_i-y_i+C)^2\)

\(y\)可以是重新排列

那么疯狂拆一下式子,化简之后就是:

\(ans=\sum_{i=1}^nx_i^2+\sum_{i=1}^ny_i^2+\sum_{i=1}^nC^2+2*C*\sum_{i=1}^n(x_i-y_i)-2*\sum_{i=1}^nx_i*y_i​\)

如果我们枚举\(C\),那么现在的任务就是算出\(\sum_{i=1}^nx_i*y_i\)的最大值,这样才能让\(ans\)最小.

怎么做呢?

如果把\(y\)数列翻转一下,那么就是:
\(\sum_{i=1}^nx_i*y_i=\sum_{i=1}^nx_i*y_{n-i}\)

这个不就是卷积?

考虑可以逆时针旋转怎么做?断环成链就好了啊.

那么就是把\(y\)串翻转然后复制一遍,求一个卷积然后走人了.

是的结束了.

代码实现

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<iostream>
using namespace std;
#define ll long long
#define re register
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
inline int gi()
{
    int f=1,sum=0;char ch=getchar();
    while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    return f*sum;
}
const int N=1000010,Inf=1e9+10;
const double Pi=acos(-1.0);
int x[N],y[N],r[N],limit,n,m,Ans[N];
struct node
{
    double x,y;
    node operator+(const node b)const{return (node){x+b.x,y+b.y};}
    node operator-(const node b)const{return (node){x-b.x,y-b.y};}
    node operator*(const node b)const{return (node){x*b.x-y*b.y,x*b.y+y*b.x};}
}A[N],B[N];
void FFT(node *A,int type)
{
    for(int i=0;i<limit;i++)
        if(i<r[i])swap(A[i],A[r[i]]);
    for(int mid=1;mid<limit;mid<<=1)
    {
        node Root=(node){cos(Pi/mid),type*sin(Pi/mid)};
        for(int R=mid<<1,j=0;j<limit;j+=R)
        {
            node Mi=(node){1,0};
            for(int k=0;k<mid;k++,Mi=Mi*Root)
            {
                node X=A[j+k],Y=Mi*A[j+mid+k];
                A[j+k]=X+Y;
                A[j+mid+k]=X-Y;
            }
        }
    }
}
void init()
{
    limit=1;int l=0;
    for(int i=0;i<n;i++)A[i].x=x[i+1];
    for(int i=0;i<n;i++)B[i].x=y[n-i];
    for(int i=0;i<n;i++)B[i+n]=B[i];
    int M=n+n-1,N=n-1;
    while(limit<=(N+M))limit<<=1,l++;
    for(int i=0;i<limit;i++)
        r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    FFT(A,1);FFT(B,1);
    for(int i=0;i<limit;i++)A[i]=A[i]*B[i];
    FFT(A,-1);
    for(int i=0;i<limit;i++)
        Ans[i]=(int)(A[i].x/limit+0.5);
}
int main()
{
    n=gi();m=gi();
    for(int i=1;i<=n;i++)x[i]=gi();
    for(int i=1;i<=n;i++)y[i]=gi();
    int pf1=0,pf2=0,sum1=0,sum2=0,ans=Inf;
    for(int i=1;i<=n;i++)pf1=pf1+x[i]*x[i];
    for(int i=1;i<=n;i++)pf2=pf2+y[i]*y[i];
    for(int i=1;i<=n;i++)sum1+=x[i];
    for(int i=1;i<=n;i++)sum2+=y[i];
    init();int Max=-Inf;
    for(int i=n-1;i<n+n;i++)Max=max(Max,Ans[i]);
    for(int C=-m;C<=m;C++)
    {
        int tot=pf1+pf2+C*C*n-2*Max+2*(sum1-sum2)*C;
        ans=min(ans,tot);
    }
    printf("%d\n",ans);
    return 0;
}

【BZOJ4827】 [Hnoi2017]礼物的更多相关文章

  1. [bzoj4827][Hnoi2017]礼物_FFT

    礼物 bzoj-4827 Hnoi-2017 题目大意:给定两个长度为$n$的手环,第一个手环上的$n$个权值为$x_i$,第二个为$y_i$.现在我可以同时将所有的$x_i$同时加上自然数$c$.我 ...

  2. [BZOJ4827][Hnoi2017]礼物(FFT)

    4827: [Hnoi2017]礼物 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1315  Solved: 915[Submit][Status] ...

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

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

  4. bzoj4827 [Hnoi2017]礼物

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

  5. bzoj千题计划303:bzoj4827: [Hnoi2017]礼物

    https://www.lydsy.com/JudgeOnline/problem.php?id=4827 式子化简一下,发现最后只跟 Σ xi*yi 有关 第二个序列反转,就可以用FFT优化 注意: ...

  6. 2018.11.16 bzoj4827: [Hnoi2017]礼物(ntt)

    传送门 nttnttntt 入门题. 考虑展开要求的式子∑i=0n−1(xi−yi−c)2\sum_{i=0}^{n-1}(x_i-y_i-c)^2∑i=0n−1​(xi​−yi​−c)2 => ...

  7. BZOJ4827: [Hnoi2017]礼物(FFT 二次函数)

    题意 题目链接 Sol 越来越菜了..裸的FFT写了1h.. 思路比较简单,直接把 \(\sum (x_i - y_i + c)^2\) 拆开 发现能提出一坨东西,然后与c有关的部分是关于C的二次函数 ...

  8. BZOJ4827:[HNOI2017]礼物(FFT)

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

  9. bzoj 4827: [Hnoi2017]礼物 [fft]

    4827: [Hnoi2017]礼物 题意:略 以前做的了 化一化式子就是一个卷积和一些常数项 我记着确定调整值还要求一下导... #include <iostream> #include ...

随机推荐

  1. echart 3 数据密集时,断点不显示问题

    如上图最开始标识的两点是不显示的,配置处理代码如下(series中配置symbolSize: 1,showAllSymbol: true): myChart.showLoading(); $.get( ...

  2. [cmd]如何设置 Windows 默认命令行窗口大小和缓冲区大小

    Windows 命令行 cmd 窗口系统默认的大小(80*40)对于现在的屏幕配置已经跟不上时代了,我们总是要把它改大些,而且缓冲区大小也想改得大大的.单纯的为当前的 Windows 命令行窗口修改显 ...

  3. 海港(NOIP2016)

    题目链接:海港 这一题怎么样呢?还好吧,也不是太难,没有用到什么特殊的算法,但写法还是很值得学习的.下面讲一下思路: 我们维护三个队列(这里我们采用自己手写的队列,因为这比STL的要快,不过这一题,S ...

  4. 2019.02.07 bzoj4784: [Zjoi2017]仙人掌(仙人掌+树形dp)

    传送门 题意:给一个无向连通图,问给它加边形成仙人掌的方案数. 思路: 先考虑给一棵树加边形成仙人掌的方案数. 这个显然可以做树形dp. fif_ifi​表示把iii为根的子树加边形成仙人掌的方案数. ...

  5. select 选中是否包含

    $("#regionname1").find("option:contains('"+regionname+"')").prop(" ...

  6. XMind使用教程

    使用XMind,可以轻松创建.管理及控制思维导图.1. 启动XMind,选择一个空白模板或模板创建:2. 单击中心主题,输入文字即可对中心主题重命名:3. 使用键盘Enter键创建主要/同级主题,使用 ...

  7. Mybatis-Plus 实战完整学习笔记(七)------select测试二

    1.查询selectOne  (3.0.3版) @Test public void selectMethod() throws SQLException { // 根据ID获取一个对象的数据 Empl ...

  8. Java编程从头开始---老妪能解

    思想导向: 今天想要分享的是最基础的东西就是如何写一个简单的代码,很多人都是小白,需要的其实并不是很高端的理论,框架和思维模式啊,设计方法啊,这些对于一个新人来说实在是好高骛远,说的那么高端,结果要学 ...

  9. 第08章:MongoDB-CRUD操作--文档--删除

    ①语法 remove()  [2.6以后方法过时] deleteOne() [2.6以后官方推荐] deleteMany() [2.6以后官方推荐] db.collection.remove( < ...

  10. c++中指针的指针和指针的引用的使用

    当指针作为函数的参数进行传递时,实际上本质上是安置传递,即将指针进行了一份拷贝,在函数的内部对这个指针的修改实际上就是对一个在函数内部的那个局部变量的修改.这点事和引用不同的,引用实际上是在参数传递时 ...