table of Contents
@desription@
Given two length n number of columns A, B. You can now be arranged in two columns weight, obtained by adding the corresponding item and then C [i] = A [i] + B [i].
Ask your maximum number of occurrences of the number of C in the congregation can be constructed, as well as the mode at this time. If there are a variety of programs, taking the maximum number of the public.
@solution@
Note \ (cnta [i] \) represents \ (I \) the number of occurrences in A, \ (CNTB [I] \) represents \ (I \) number of occurrences of B. The maximum number of occurrences of p in C \ (\ sum_ I = {0}} ^ {p \ min (CNTA [I], CNTB [PI]) \) .
Notice that it looks like a special convolution. We remember \ (Fa_i (X) = \ sum_ P = {0}} ^ {MAX [CNTA [P] = I] {X ^ P} \) , empathy note \ (Fb_i (x) = \ sum_ {p ^ MAX {0} =} [CNTB [P] = I] X ^ P \) . The answer:
\ [G (X) = \ sum_ {I =. 1} ^ {n-} I \ Times (Fa_i (X) (\ sum_ {J = I +. 1} ^ {n-} Fb_j (X)) + Fb_i (x) (\ sum_ {j = i + 1} ^ {n} Fa_j (x)) + Fa_i (x) Fb_i (x)) \]
But this does not count as fast violence.
Noting \ (\ CNTA SUM [i] = n-\) , that is if i is greater, to meet cnta [p] = i of p will be less.
Specifically, A in cnta [p] ≥ K have \ (O (\ frac {n } {K}) \) a, B is also a \ (O (\ frac {n } {K}) \) . Then we can enumerate every possible violent tuple calculation, the time complexity is \ (O (\ FRAC ^ {n-2} 2 ^ {K}) \) .
When K is large, this violence algorithm with respect to the above convolution method, in fact, is very fast.
So the complexity and loved equilibrium time: for i <K, convolution calculation complexity is \ (O (K \ MAX Times \ Times \ log MAX) \) ; for i> = K, enumeration violence , complexity is \ (O (\ frac {n
^ 2} {K ^ 2}) \) since n and MAX same order, we direct cause \ (Kn \ log n = \ frac {n ^ 2} {K ^ 2} \) , the solution was \ (K = (\ {n-FRAC} {\ n-log}) ^ {\ FRAC. 1 {{}}}. 3 \) .
Then the total time complexity \ (O (n-^ {\ FRAC. 4} {} {}. 3 \ Times \ ^ {log \ FRAC. 3} {2} {} n-) \) , while looking very bad but actually quite excellent of.
@accepted code@
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
const int MOD = 998244353;
const int MAXN = (1 << 17);
const int K = 18;
const int G = 3;
inline int add(int x, int y) {return (x + y >= MOD ? x + y - MOD : x + y);}
inline int sub(int x, int y) {return (x - y < 0 ? x - y + MOD : x - y);}
inline int mul(int x, int y) {return 1LL * x * y % MOD;}
int pow_mod(int b, int p) {
int ret = 1;
for(int i=p;i;i>>=1,b=mul(b,b))
if( i & 1 ) ret = mul(ret, b);
return ret;
}
int w[22], iw[22];
void init() {
for(int i=0;i<22;i++) {
w[i] = pow_mod(G, (MOD - 1) / (1 << i));
iw[i] = pow_mod(w[i], MOD - 2);
}
}
int length(int n) {
int len; for(len = 1; len < n; len <<= 1);
return len;
}
void ntt(int *A, int n, int type) {
for(int i=0,j=0;i<n;i++) {
if( i < j ) swap(A[i], A[j]);
for(int k=(n>>1);(j^=k)<k;k>>=1);
}
for(int i=1;(1<<i)<=n;i++) {
int s = (1 << i), t = (s >> 1);
int u = (type == 1 ? w[i] : iw[i]);
for(int j=0;j<n;j+=s) {
for(int k=0,p=1;k<t;k++,p=mul(p,u)) {
int x = A[j+k], y = mul(p, A[j+k+t]);
A[j+k] = add(x, y), A[j+k+t] = sub(x, y);
}
}
}
if( type == -1 ) {
int iv = pow_mod(n, MOD - 2);
for(int i=0;i<n;i++)
A[i] = mul(A[i], iv);
}
}
class SumOfArrays{
public:
vector<pair<int, int> >na, nb;
int f[2*MAXN + 5];
int ca[MAXN + 5], cb[MAXN + 5];
int a[MAXN + 5], b[MAXN + 5];
int ta1[2*MAXN + 5], ta2[2*MAXN + 5], tb1[2*MAXN + 5], tb2[2*MAXN + 5], tmp[2*MAXN + 5];
string findbestpair(int n, vector<int>A, vector<int>B) {
init();
a[0] = A[0], a[1] = A[1], b[0] = B[0], b[1] = B[1];
for(int i=2;i<n;i++) {
a[i] = (1LL*A[2]*a[i-1]%A[5] + 1LL*A[3]*a[i-2]%A[5] + A[4]) % A[5];
b[i] = (1LL*B[2]*b[i-1]%B[5] + 1LL*B[3]*b[i-2]%B[5] + B[4]) % B[5];
}
for(int i=0;i<n;i++)
ca[a[i]]++, cb[b[i]]++;
for(int i=0;i<MAXN;i++) {
if( ca[i] >= K ) na.push_back(make_pair(i, ca[i]));
if( cb[i] >= K ) nb.push_back(make_pair(i, cb[i]));
}
for(int i=0;i<(int)na.size();i++)
for(int j=0;j<(int)nb.size();j++)
f[na[i].first + nb[j].first] += min(na[i].second, nb[j].second);
for(int i=1;i<K;i++) {
bool flag = false;
for(int j=0;j<MAXN;j++) {
if( ca[j] > i ) ta1[j]++;
else if( ca[j] == i ) ta2[j]++, flag = true;
if( cb[j] > i ) tb1[j]++;
else if( cb[j] == i ) tb2[j]++, flag = true;
}
int len = 2*MAXN;
if( flag ) {
ntt(ta1, len, 1), ntt(ta2, len, 1), ntt(tb1, len, 1), ntt(tb2, len, 1);
for(int j=0;j<len;j++)
tmp[j] = add(add(mul(ta1[j], tb2[j]), mul(ta2[j], tb1[j])), mul(ta2[j], tb2[j]));
ntt(tmp, len, -1);
for(int j=0;j<len;j++)
f[j] = add(f[j], mul(tmp[j], i));
}
for(int j=0;j<len;j++) ta1[j] = ta2[j] = tb1[j] = tb2[j] = tmp[j] = 0;
}
int ans = 0, res;
for(int i=2*MAXN-1;i>=0;i--)
if( f[i] > ans ) ans = f[i], res = i;
string ret = "";
while( res ) ret = (char)(res % 10 + '0') + ret, res /= 10;
ret = " " + ret;
while( ans ) ret = (char)(ans % 10 + '0') + ret, ans /= 10;
return ret;
}
};
@details@
Why should the function returns the value of the form into such crimes against humanity, but also the number converted to a string. Direct returns an array is not very good.