@desription@

给定两个长度为 n 的数列 A, B。现你可以将两数列重排列,然后对应项相加得到 C[i] = A[i] + B[i]。

问你所能构造的 C 中众数的最大出现次数,以及此时的众数。如果有多种方案,取最大的众数。

原题传送门。

@solution@

记 \(cnta[i]\) 表示 \(i\) 在 A 中的出现次数,\(cntb[i]\) 表示 \(i\) 在 B 中的出现次数。则 p 在 C 中的最大出现次数为 \(\sum_{i=0}^{p}\min(cnta[i], cntb[p-i])\)。

注意到它长得特别像个卷积。我们记 \(Fa_i(x) = \sum_{p=0}^{MAX} [cnta[p] = i]x^{p}\),同理记 \(Fb_i(x) = \sum_{p=0}^{MAX} [cntb[p] = i]x^p\)。则答案:

\[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))
\]

不过这样算还不如暴力快。

注意到 \(\sum cnta[i] = n\),也就是说如果 i 越大,满足 cnta[p] = i 的 p 会越少。

具体而言,A 中 cnta[p] ≥ K 有 \(O(\frac{n}{K})\) 个,B 中也有 \(O(\frac{n}{K})\)。那么我们可以枚举每一个可能的二元组暴力计算,时间复杂度为 \(O(\frac{n^2}{K^2})\)。

当 K 较大时,这个暴力算法相对于上面的卷积方法而言,其实是非常快的。

于是又到了喜闻乐见的复杂度平衡时间:对于 i < K,使用卷积计算,复杂度为 \(O(K\times MAX\times \log MAX)\);对于 i >= K,使用暴力枚举,复杂度为 \(O(\frac{n^2}{K^2})\)

因为 n 与 MAX 同阶,我们直接令 \(Kn\log n = \frac{n^2}{K^2}\),解得 \(K = (\frac{n}{\log n})^{\frac{1}{3}}\)。

然后总时间复杂度 \(O(n^{\frac{4}{3}}\times \log^{\frac{2}{3}}n )\),虽然看着挺糟不过其实挺优秀的。

@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@

为什么要把函数返回值设置成这么反人类形式,还要把数转化成字符串。直接返回一个数组不挺好的。

@topcoder - SRM603D1L3@ SumOfArrays的更多相关文章

  1. TopCoder kawigiEdit插件配置

    kawigiEdit插件可以提高 TopCoder编译,提交效率,可以管理保存每次SRM的代码. kawigiEdit下载地址:http://code.google.com/p/kawigiedit/ ...

  2. 记第一次TopCoder, 练习SRM 583 div2 250

    今天第一次做topcoder,没有比赛,所以找的最新一期的SRM练习,做了第一道题. 题目大意是说 给一个数字字符串,任意交换两位,使数字变为最小,不能有前导0. 看到题目以后,先想到的找规律,发现要 ...

  3. TopCoder比赛总结表

    TopCoder                        250                              500                                 ...

  4. Topcoder几例C++字符串应用

    本文写于9月初,是利用Topcoder准备应聘时的机试环节临时补习的C++的一部分内容.签约之后,没有再进行练习,此文暂告一段落. 换句话说,就是本文太监了,一直做草稿看着别扭,删掉又觉得可惜,索性发 ...

  5. TopCoder

    在TopCoder下载好luncher,网址:https://www.topcoder.com/community/competitive%20programming/ 选择launch web ar ...

  6. TopCoder SRM 596 DIV 1 250

    body { font-family: Monospaced; font-size: 12pt } pre { font-family: Monospaced; font-size: 12pt } P ...

  7. 求拓扑排序的数量,例题 topcoder srm 654 div2 500

    周赛时遇到的一道比较有意思的题目: Problem Statement      There are N rooms in Maki's new house. The rooms are number ...

  8. TopCoder SRM 590

     第一次做TC,不太习惯,各种调试,只做了一题...... Problem Statement     Fox Ciel is going to play Gomoku with her friend ...

  9. Topcoder Arena插件配置和训练指南

    一. Arena插件配置 1. 下载Arena 指针:http://community.topcoder.com/tc?module=MyHome 左边Competitions->Algorit ...

随机推荐

  1. Postgres的索引01

    一.PG 9.3有以下索引类型 1.b-tree 1.1支持前导模糊查询,如xxx%或者^'xxx' 1.2忽略大小写字符前导模糊查询,如ILIKE 'XXX%'或者~*'^xxx' 1.3支持常见的 ...

  2. 51Nod - 1255

    也是第十一届校赛的C题,不过他把1e5改成了1e7. 一开始就想到用贪心做.思路是这样的:开一个字符数组ans保存答案.然后从头到尾遍历题目给出的字符串S,如果ans数组中还没有这个字母,那么就把字母 ...

  3. 特效 css3 渐变背景框

    .box{ 子级 position: relative; width: 300px; height: 400px; display: flex; justify-content: center; al ...

  4. arch 系列manjaro更新deepin-screenshot没有图标

    问题描述 deepin软件安装到其他分支后,这个问题出现,相信各位一点都不意外,原因不细说,简单的概括就是没有DDE的桌面环境!! 简单介绍 deepin-screen截图软件在使用的时候是深受国人的 ...

  5. 【JavaScript数据结构系列】03-队列Queue

    [JavaScript数据结构系列]03-队列Queue 码路工人 CoderMonkey 转载请注明作者与出处 1. 认识队列Queue结构 队列,跟我们的日常生活非常贴近,我们前面举例了食堂排队打 ...

  6. VS中自定义代码片段

    VS - 工具 - 代码片段管理器 实现:propnotify 加 Tab 键 生成属性定义代码片段 (包含一个字段定义,一个属性get/set定义,其中set会触发属性值变更事件) <?xml ...

  7. Maven快速入门(二)手动创建maven项目hellomaven

    之前讲过Maven介绍及环境搭建,介绍了maven的作用和如何搭建maven环境.接下来就以一个helloworld的例子来说一说如何创建maven项目以及maven项目的项目结构,最后讲maven如 ...

  8. [JavaWeb基础] 012.Struts2 自定义标签使用

    在做开发中,我们会把一些比较经常使用到的代码封装起来,这样可以加快开发的速度和减少错误,并且在修改bug可以一次修改多次修复.那么在前端页面上,如果我们要经常用到公用的显示功能,并涉及到服务端逻辑操作 ...

  9. Rocket - jtag - JtagStateMachine

    https://mp.weixin.qq.com/s/cFXVOBHayV2w27jpT5RglA 简单介绍JtagStateMachine的实现. 1. 简单介绍 根据IEEE 1149.1-200 ...

  10. JavaSE(三) 变量与运算符

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 2 变量的使用 2.1按数据类型分类 ​ 整型 : byte(1字节 = 8bit) short(2字节 ...