loj#2020. "HNOI2017" gift (FFT)

Put the code first, and update it later (*3)

============================= 2018.3.24UPD ===================== =========
The topic is here

practice

It felt like there was nothing to say. After converting the formula directly, fft will do. Push the style yourself, be careful to push it better (Fog
upd : Omg, I feel that I am too irresponsible. Let's post a more detailed link ... //Professional dumping the pot

code

/*
*   转化式子;
*   多项式套路:翻转后fft;
*/
#include<bits/stdc++.h>
#define rep(i,x,y) for (int i=(x); i<=(y); i++)
#define per(i,x,y) for (int i=(x); i>=(y); i--)
#define N 400010
#define ll long long
#define inf 1000000000000000ll
#define sqr(x) ((x)*(x))
using namespace std;
int m,x[N],y[N],n1,r[N],len,n; ll ans=0,sumx,sumy,C,ret=inf;
const long double pi=acos(-1);
struct comp{
    long double a,b;
    comp(){ a=0,b=0; } comp(long double x,long double y){ a=x,b=y; }
}a[N],b[N],c[N],w[2][N];
comp operator + (comp x,comp y) { return comp(x.a+y.a,x.b+y.b); }
comp operator - (comp x,comp y) { return comp(x.a-y.a,x.b-y.b); }
comp operator * (comp x,comp y) { return comp(x.a*y.a-x.b*y.b,x.a*y.b+x.b*y.a); }
void fft(comp a[N],int all,int fl){
    rep (i,0,all) if (i<r[i]) swap(a[i],a[r[i]]);
    int n=2,m; comp t;
    while (n<=all){
        m=n/2;
        for (int i=0; i<all; i+=n)
            for (int k=0; k<m; k++){
                t=w[fl][all/n*k]*a[i+m+k];
                a[i+m+k]=a[i+k]-t;
                a[i+k]=a[i+k]+t;
            }
        n<<=1;
    }
    if (fl) rep (i,0,n-1) a[i].a/=all;
}
void solve(){
    rep (i,1,n1) x[i]=0;
    reverse(y+1,y+1+2*n1);
    len=0; n=1;
    for (; n<=4*n1; n<<=1,len++);
    rep (i,0,n-1) r[i]=(r[i>>1]>>1)|((i&1)<<len-1);
    rep (i,0,n-1) w[0][i]=comp(cos(2*i*pi/n),sin(2*i*pi/n));
    rep (i,0,n-1){ w[1][i]=w[0][i]; w[1][i].b=-w[1][i].b; }
    rep (i,0,n-1) a[i]=comp(x[i],0);
    rep (i,0,n-1) b[i]=comp(y[i],0);
    fft(a,n,0); fft(b,n,0);
    rep (i,0,n-1) c[i]=a[i]*b[i];
    fft(c,n,1);
    rep (i,2*n1+2,3*n1+1) ret=min(ret,-(ll)(c[i].a+0.5)*2);
}
int main(){
    /*freopen("C.in","r",stdin);
    freopen("C.out","w",stdout);*/
    scanf("%d%d",&n1,&m);
    rep (i,1,n1){ scanf("%d",&x[i]); x[i+n1]=x[i]; }
    rep (i,1,n1){ scanf("%d",&y[i]); y[i+n1]=y[i]; }
    sumx=sumy=0;
    rep (i,1,n1){ ans+=sqr(x[i])+sqr(y[i]); sumx+=x[i]; sumy+=y[i]; }
    if (sumx>sumy){ swap(x,y); swap(sumx,sumy); }
    C=(ll)(-(long double)(sumx-sumy)/n1+0.5);
    //printf("C=%lld\n",C);
    solve();
    printf("%lld\n",ans+ret+2ll*(sumx-sumy)*C+n1*sqr(C));
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325940202&siteId=291194637
FFT