1. 程式人生 > >HNOI2017禮物

HNOI2017禮物

static ger pan sig min write open define put

禮物
  • 這估計是最水,最無腦的一道題了
  • 首先發現總和最接近時答案最小
  • 發現答案就是\((\sum_{i=1}^{n}a[i]^2+b[i]^2)-2*max(\sum_{i=1}^{n}a[i]*b[i+j])(0<=j<=n-1)\)
  • 前面隨便算,主要是後面那個式子,其實就是兩個數列錯位相乘加起來最大值
  • \(b\)反過來就變成\(\sum_{i=1}^{n}a[i]*b[n-i-j])(0<=j<=n-1)\),直接就多項式卷積,FFT一算就行了。

    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    using namespace
    std; typedef int sign; typedef long long ll; #define For(i,a,b) for(register sign i=(sign)a;i<=(sign)b;++i) #define Fordown(i,a,b) for(register sign i=(sign)a;i>=(sign)b;--i) const int N=5e4+5; bool cmax(ll &a,ll b){return (a<b)?a=b,1:0;} bool cmin(ll &a,ll b){return (a>b)?a=b,1:0
    ;} template<typename T>inline T read() { T f=1,ans=0; char ch=getchar(); while(!isdigit(ch)&&ch!=‘-‘)ch=getchar(); if(ch==‘-‘)f=-1,ch=getchar(); while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch-‘0‘),ch=getchar(); return ans*f; } template<typename T>inline void write(T x,char
    y) { if(x==0) { putchar(‘0‘);putchar(y); return; } if(x<0) { putchar(‘-‘); x=-x; } static char wr[20]; int top=0; for(;x;x/=10)wr[++top]=x%10+‘0‘; while(top)putchar(wr[top--]); putchar(y); } void file() { #ifndef ONLINE_JUDGE freopen("3723.in","r",stdin); freopen("3723.out","w",stdout); #endif } struct comp { double r,v; comp operator + (const comp &x) const {return (comp){r+x.r,v+x.v};} comp operator - (const comp &x) const {return (comp){r-x.r,v-x.v};} comp operator * (const comp &x) const {return (comp){r*x.r-v*x.v,r*x.v+v*x.r};} }; comp a[N<<2],b[N<<2]; int m,n,t; int rev[N<<2]; int sum1,sum2; void input() { n=read<int>();t=read<int>();m=n-1; For(i,0,m)a[i].r=read<int>(),sum1+=a[i].r; For(i,0,m)b[m-i].r=read<int>(),sum2+=b[m-i].r; } void init() { if(sum1>sum2)swap(a,b),swap(sum1,sum2); int temp=(sum2-sum1)/n; if(sum1+(temp+1)*n-sum2<sum2-sum1-temp*n)temp++; For(i,0,m)a[i].r+=temp; m<<=1; int cnt=0; for(n=1;n<=m;n<<=1)cnt++; for(int i=0;i<n;i++)rev[i]=(rev[i>>1]>>1)|((i&1)*(1<<(cnt-1))); } const double pi=acos(-1.0); ll ans; void FFT(comp *p,int type) { int i,j,k,num; for(i=0;i<n;i++)if(i<rev[i])swap(p[i],p[rev[i]]); for(i=2;i<=n;i<<=1) { comp wi={cos(pi*2/i),sin(pi*2/i)*type}; num=i>>1; for(j=0;j<n;j+=i) { comp x={1,0}; for(k=0;k<num;k++,x=x*wi) { comp u=p[j+k],v=p[j+k+num]*x; p[j+k]=u+v; p[j+k+num]=u-v; } } } } int w[N<<2]; void work() { //For(i,0,m>>1)write((int)a[i].r,i==m/2?‘\n‘:‘ ‘); //For(i,0,m>>1)write((int)b[i].r,i==m/2?‘\n‘:‘ ‘); ll res=0; For(i,0,m>>1)ans+=a[i].r*a[i].r+b[i].r*b[i].r; FFT(a,1);FFT(b,1); for(int i=0;i<n;i++)a[i]=a[i]*b[i]; FFT(a,-1); for(int i=0;i<n;i++)w[i]=(int)(a[i].r/n+0.5); m>>=1; For(i,0,m-1)cmax(res,w[i]+w[i+m+1]); write(ans-res*2,\n); } int main() { file(); input(); init(); work(); return 0; }

HNOI2017禮物