设旋转好后我们加的值是(c.)
[sum_{i=0}^n (a_i-b_i+c)^2
]
[=sum a_i^2+b_i^2+c^2-2a_ib_i+2a_ic-2b_ic
]
这个式子除了(sum -2a_ib_i)都是定值。考虑求这个东西的最大值。
把(-2)扔了,原式:
[sum a_ib_i
]
反转(a)得到:
[sum a_{n-i+1}b_i
]
这玩意是个卷积。
于是把(a)反转后倍长并与(b)进行卷积,取(iin left{n+1,n+2... ight}[x^i]F(x))的最大值即可。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod=998244353;
const int N=310000;
inline int add(int x,int y){return (x+y)%mod;}
inline int mul(int x,int y){return 1ll*x*y%mod;}
inline int qpow(int a,int b){
int res=1;
while(b){
if(b&1)res=mul(res,a);
a=mul(a,a);b>>=1;
}
return res;
}
int n,rev[N],a[N],b[N],c[N],f[N],m;
void NTT(int *a,int lim,int tp){
for(int i=0;i<lim;++i)if(i<rev[i])swap(a[i],a[rev[i]]);
for(int i=1;i<lim;i<<=1){
int gn=qpow(3,(mod-1)/(i<<1));
if(tp==-1)gn=qpow(gn,mod-2);
for(int j=0;j<lim;j+=(i<<1)){
int G=1;
for(int k=0;k<i;++k,G=mul(G,gn)){
int x=a[j+k],y=mul(G,a[i+j+k]);
a[j+k]=add(x,y);a[i+j+k]=add(x,mod-y);
}
}
}
if(tp==1)return;
int inv=qpow(lim,mod-2);
for(int i=0;i<lim;++i)a[i]=mul(a[i],inv);
}
int ans,Ans;
int sa,sb;
signed main(){
scanf("%lld%lld",&n,&m);
int lim=1,len=0;
while(lim<=(n+n+n))lim<<=1,len++;
for(int i=1;i<lim;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(len-1));
for(int i=0;i<n;++i)scanf("%lld",&a[i]);
for(int i=0;i<n;++i)scanf("%lld",&b[i]);
for(int i=0;i<n;++i)ans+=a[i]*a[i]+b[i]*b[i];
for(int i=0;i<n;++i)sa+=a[i],sb+=b[i];
sa<<=1,sb<<=1;
reverse(a,a+n);
for(int i=n;i<(n<<1);++i)a[i]=a[i-n];
NTT(a,lim,1);NTT(b,lim,1);
for(int i=0;i<lim;++i)a[i]=mul(a[i],b[i]);
int mx=-1;
NTT(a,lim,-1);
for(int i=n;i<(n<<1);++i)mx=max(mx,a[i]);
Ans=(1<<30);
for(int i=-m;i<=m;++i){Ans=min(Ans,ans-2*mx-sb*i+sa*i+n*i*i);}
printf("%lld
",Ans);
return 0;
}