zoukankan      html  css  js  c++  java
  • [2016北京集训试题15]项链-[FFT]

    Description

    Solution

    设y[i+k]=y[i]+n。

    由于我们要最优解,则假如将x[i]和y[σ[i]]连线的话,线是一定不会交叉的。

    所以,$ans=sum (x_{i}-y_{i+s}+c)^{2}$

    拆开得$ans=sum (x_{i}^{2}+y_{i+s}^{2}+c^{2}-2x_{i}y_{i+s}+2x_{i}c-2y_{i+s}c)$

    其中,$x_{i}y_{i+s}$是卷积形式。

    我们把经过处理的y数组reverse一下,和x数组进行卷积(这里用ntt似乎会爆常数,fft大法好)。然后针对不同的s,得到以c为未知数的所有常数或系数,ans就是一个二次函数了。c用公式解就可以。

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const double pi=acos(-1);
    struct C
    {
        double r,i;
        friend C operator+(C a,C b){return C{a.r+b.r,a.i+b.i};}
        friend C operator*(C a,C b){return C{a.r*b.r-a.i*b.i,a.i*b.r+a.r*b.i};}
        friend C operator-(C a,C b){return C{a.r-b.r,a.i-b.i};}
    }fx[100010],fy[100010];
    int rev[100010];
    void fft(C *num,int n,int dft)
    {
        for (int i=1;i<n;i++)
            if (i<rev[i]) swap(num[i],num[rev[i]]);
        for (int step=1;step<n;step<<=1)
        {
            C wn{cos(pi/step),sin(pi/step)*dft};
            for (int j=0;j<n;j+=step*2)//从0开始! 
            {
                C w{1,0};
                for (int k=0;k<step;k++,w=w*wn)
                {
                    C x=num[j+k],y=w*num[j+k+step];
                    num[j+k]=x+y;
                    num[j+k+step]=x-y;
                }
            }
        }
        if (dft==-1) for (int i=0;i<n;i++) num[i].r/=n;
    }
    int T,n,k,len,L;
    int x[4010],y[8010];
    ll sumx[8010],sumy[8010],sumx2[8010],sumy2[8010];
    int main()
    {
        scanf("%d",&T);
        while (T--)
        {
            scanf("%d%d",&n,&k);
            memset(sumx,0,sizeof(sumx));
            memset(sumy,0,sizeof(sumy));
            memset(sumx2,0,sizeof(sumx2));
            memset(sumy2,0,sizeof(sumy2));
            memset(fx,0,sizeof(fx));memset(fy,0,sizeof(fy));        
            for (int i=1;i<=k;i++) 
            {
                scanf("%d",&x[i]);
                sumx[i]=sumx[i-1]+x[i],sumx2[i]=sumx2[i-1]+1ll*x[i]*x[i];   
            }
            for (int i=1;i<=k;i++) 
            {scanf("%d",&y[i]);y[k+i]=y[i]+n;}
            for (int i=1;i<=2*k;i++)
            sumy[i]=sumy[i-1]+y[i],sumy2[i]=sumy2[i-1]+1ll*y[i]*y[i];
             
            for (int i=1;i<=k;i++) fx[i-1].r=x[i];
            for (int i=0,j=2*k;j;i++,j--) fy[i].r=y[j];
            len=1,L=0;
            for (;len<2*k;len<<=1,L++);
            L++;len<<=1;
            for (int i=0;i<len;i++) rev[i]=(rev[i>>1]>>1)|(i&1)<<(L-1);
            fft(fx,len,1);fft(fy,len,1);
            for (int i=0;i<len;i++) fx[i]=fx[i]*fy[i];
            fft(fx,len,-1);
            ll re,c,b,ans=1e13;
            for (int i=2*k-1,j=0;i>=k;i--,j++)
            {
                re=fx[i].r+0.2;
                re=-2*re+sumx2[k]+sumy2[j+k]-sumy2[j];
                b=2*(sumx[k]-sumy[j+k]+sumy[j]);
                c=-b/(2*k);
                ans=min(ans,k*c*c+c*b+re);
                c++;
                ans=min(ans,k*c*c+c*b+re);
            }
            cout<<ans<<endl;
        }
    }
  • 相关阅读:
    jvm性能监控(4)–JVM的监控工具Jconsole
    jvm性能监控(3)-jdk自带工具 jps jstack jmap
    jvm性能监控(2)–JVM的监控工具jstat
    jvm(1)性能监控-linux相关命令
    jvm学习(5) 对象的创建与结构
    jvm(4) 对象创建
    jvm学习(3)方法区、堆、对象存储位置
    jvm学习(2)JVM内存说明
    java泛型
    windows下部署spring boot 的jar
  • 原文地址:https://www.cnblogs.com/coco-night/p/9715310.html
Copyright © 2011-2022 走看看