传送门

(摸肚皮)真的真的真的真的扯不动了。

答案长这样:$\sum\limits(x-y+c)^2$

拆一下式子:$\sum\limits x^2-2xy+y^2+c^2+2cx-2cy$

把带$c$的提出来:$nc^2+2c(\sum x-\sum y)$

这不一二次函数吗?由于两个手环都可以加$c$,所以$c$实际上可以取任意整数。

考虑到精度问题,$c$为整数,而且$m\le 100$,直接$O(m)$枚举求最小值都行。

然后带$c$的成了常数项,$x^2+y^2$也是常数项,就剩了个$-\sum 2xy$

把$y$序列翻转后面补$0$,$x$序列拷贝一份接到后面,这个式子就成了$-2\sum\limits_{j=0}^i x_jy_{i-j}$

$NTT$卷起来就完了。

代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>

#define maxn 135005
#define inf 0x3f3f3f3f

const int mod = 998244353;
const int g = 3;

using namespace std;

inline int read(){
    int x=0,y=0;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')y=1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    return y?-x:x;
}
inline int quickpow(int x,int y=mod-2){
    int ans=1;
    while(y){
        if(y&1)ans=1ll*ans*x%mod;
        x=1ll*x*x%mod,y>>=1;
    }
    return ans;
}
const int ig = quickpow(g);
int a[maxn],b[maxn],rev[maxn];
inline int mix(int x,int y){return x+y>=mod?x+y-mod:x+y;}
void NTT(int *f,int n,bool type){
    for(register int i=0;i<n;++i)if(i<rev[i])swap(f[i],f[rev[i]]);
    for(register int p=2;p<=n;p<<=1){
        int len=p>>1,o=quickpow(type?ig:g,(mod-1)/p);
        for(register int i=0;i<n;i+=p){
            int gen=1,cop;
            for(register int j=i;j<i+len;++j){
                cop=1ll*f[j+len]*gen%mod;
                f[j+len]=mix(f[j],mod-cop),f[j]=mix(f[j],cop),gen=1ll*gen*o%mod;
            }
        }
    }
    if(type){
        int inv=quickpow(n);
        for(register int i=0;i<n;++i)a[i]=1ll*a[i]*inv%mod;
    }
}
int main(){
    int n=read(),m=read(),sum=0,base=0,mi=inf,lim=1,ans=0;
    for(register int i=0;i<n;++i)a[i]=a[i+n]=read();
    for(register int i=0;i<n;++i)b[i]=read(),sum+=a[i]-b[i],base+=a[i]*a[i]+b[i]*b[i];
    sum<<=1,reverse(b,b+n);
    for(register int i=-m;i<=m;++i)mi=min(mi,n*i*i+sum*i);
    base+=mi;
    while(lim<=n<<1)lim<<=1;
    for(register int i=0;i<lim;++i)rev[i]=(rev[i>>1]>>1)|(i&1?lim>>1:0);
    NTT(a,lim,0),NTT(b,lim,0);
    for(register int i=0;i<lim;++i)a[i]=1ll*a[i]*b[i]%mod;
    NTT(a,lim,1);
    for(register int i=n-1;i<(n<<1)-1;++i)ans=max(ans,a[i]<<1);
    printf("%d\n",base-ans);
}