Hero has two arrays of integers: A and B. Each of the arrays contains exactly n elements.
Hero will do two things with his arrays: First, he will permute the elements in each of his arrays somehow. (He is allowed to put the elements of each array into any order he likes, including their original order. He is not allowed to swap elements between A and B, each array has to be rearranged separately.) Afterwards, he will produce a new array C of n elements such that for all i, C[i] = A[i] + B[i].
Hero likes equal numbers. His goal is to produce as many equal numbers in C as possible. Formally, for a given C he is interested in integers X and Y such that the array C contains X occurrences of the value Y, and X is as large as possible.
题解:
其实就是让你求这玩意儿:
其中aiai为ii在数组中的出现次数,
这个式子一般情况下是不能FFTFFT的,不过观察到aa和所有数加起来也不过nn个,我们可以分段解决。
设为阀值,小于LL的位置我们做次FFTFFT,大于LL的直接暴力匹配,复杂度为:。
当L=(nlogn)31L=(nlogn)31时最优,复杂度为O(n43log23n)O(n43log23n)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=2e6+50,L=20,mod=998244353,G=3;
inline int add(int x,int y) {return (x+y>=mod)?(x+y-mod):(x+y);}
inline int dec(int x,int y) {return (x-y<0)?(x-y+mod):(x-y);}
inline int mul(int x,int y) {return (LL)x*y%mod;}
inline int power(int a,int b) {
int rs=1;
for(;b;b>>=1, a=mul(a,a)) if(b&1) rs=mul(rs,a);
return rs;
}
int k,a[N],b[N],c[N],ca[N],cb[N],cc[N],ta[N],tb[N],tc[N],pos[N],w[N],mx;
inline void init(int len) {
for(k=1;k<=len;k<<=1);
for(int i=1;i<k;i++) pos[i]=(i&1)?((pos[i>>1]>>1)^(k>>1)):(pos[i>>1]>>1);
}
inline void dft(int *a) {
for(int i=1;i<k;i++) if(pos[i]>i) swap(a[pos[i]],a[i]);
for(int bl=1;bl<k;bl<<=1) {
int tl=bl<<1, wn=power(G,(mod-1)/tl); w[0]=1;
for(int i=1;i<bl;i++) w[i]=mul(w[i-1],wn);
for(int bg=0;bg<k;bg+=tl)
for(int j=0;j<bl;j++) {
int &t1=a[bg+j], &t2=a[bg+j+bl], t=mul(t2,w[j]);
t2=dec(t1,t); t1=add(t1,t);
}
}
}
inline void calc() {
for(int i=0;i<k;i++) ta[i]=tb[i]=0;
for(int i=0;i<=mx;i++) ta[i]=(ca[i]?(--ca[i],1):0), tb[i]=(cb[i]?(--cb[i],1):0);
for(int i=mx+1;i<k;i++) ta[i]=tb[i]=0;
dft(ta); dft(tb); const int inv=power(k,mod-2);
for(int i=0;i<k;i++) tc[i]=mul(ta[i],tb[i]);
dft(tc); reverse(tc+1,tc+k);
for(int i=0;i<k;i++) cc[i]+=mul(tc[i],inv);
}
inline string tostring(int x) {
static int buf[50];
string t;
if(!x) {return "0";}
while(x) {buf[++buf[0]]=x%10; x/=10;}
while(buf[0]) t+=char('0'+buf[buf[0]--]);
return t;
}
class SumOfArrays {
public:
string findbestpair(int n, vector<int> Aseed, vector<int> Bseed) {
a[0]=Aseed[0]; a[1]=Aseed[1]; b[0]=Bseed[0]; b[1]=Bseed[1];
for(int i=2;i<n;i++) {
a[i]=((LL)a[i-1]*Aseed[2]+(LL)a[i-2]*Aseed[3]+Aseed[4])%Aseed[5];
b[i]=((LL)b[i-1]*Bseed[2]+(LL)b[i-2]*Bseed[3]+Bseed[4])%Bseed[5];
}
mx=*max_element(a,a+n)+*max_element(b,b+n); init(mx);
for(int i=0;i<n;i++) ca[a[i]]++, cb[b[i]]++;
for(int i=1;i<=L;i++)
calc();
ta[0]=0; tb[0]=0;
for(int i=0;i<=mx;i++) {
if(ca[i]) ta[++ta[0]]=i;
if(cb[i]) tb[++tb[0]]=i;
}
for(int i=ta[0];i;i--)
for(int j=tb[0];j;j--)
cc[ta[i]+tb[j]]=add(cc[ta[i]+tb[j]],min(ca[ta[i]],cb[tb[j]]));
int ans=0;
for(int i=0;i<=mx;i++)
if(cc[ans]<=cc[i]) ans=i;
return tostring(cc[ans])+" "+tostring(ans);
}
};