2020牛客暑期多校训练营第二场
比赛链接
https://ac.nowcoder.com/acm/contest/15688?&headNav=www
A All with Pairs
题意
给你字符串n个字符串$s_1$,$s_2$,$s_3$,… $s_n$给你函数$f(s,t)$,其值为最大的长度w,使得s的长度为w的前缀和t的长度为w的后缀相同完全。
你要计算
$$
\sum_{i=1}^{n}\sum_{i=1}^{n}f(s_i,s_j)^2 \mod 998244353
$$
数据范围
$n<10^5$, 字符串总长度小于$10^6$
题解
我们枚举i,把前i个字符串对每一个后缀都hash,然后放入map,最后枚举$s_i$的前缀,在map中寻找此前缀的hash,然后即可对$f(s_i,s_j)$实现计数,最后把增加到值添加到答案中。复杂度$O(len\cdot\log(len))$。len为字符串总长。
B Boundary
题意
给你二维平面到n个点,你要找一个经过原点的圆,穿过尽可能多的点。
数据范围
最多2000个点。
题解
三个点可以确定一个圆,由于有一个点在原点,所以我们枚举另外两个点。则可以唯一确定圆,对圆进行hash,然后计数,计数最多的那个就是答案。
1 |
|
C Cover the Tree
题意
给你一个无根树,你需要使用最少的链使得这棵树的每条边至少被一条链覆盖。
数据范围
$节点个数n<2\times 10^5$
题解
贪心,我们让每条链的端点都选择度数为1的结点。
我们使用一个度数为1的结点当作根,把树展开为平面结构,树根在上,叶子在下,显然我们直接让最左边的叶子连接最右边的叶子即可,最后有两种情况,
剩余一个结点,我们直接让他和根结点相连。
不剩余任何结点,但是最后连接的两个结点形成的链只能覆盖到lca,所以我们让根与那个lca相连即可。
1 |
|
E Exclusive OR
题意
给你长度为n的序列a,对于1到n的每一个数字i,你都要计算这个序列精确选择i个数字能异或出来的最大异或和。
ps : 数字可以重复选择。
数据范围
$a_i<2^{18}$
题解
不难证明当n大于36以后,都是异或最大值。对于小于36的情况,使用fwt快速计算即可。
证明:
对于18位的二进制数,其线性基的个数最多是18,所以18个数及以内一定能能够异或出最大的值,这个值是上确届,不妨设x个数能达到这个上届,其中$x\le18$
然后考虑$x+2k$, $k\ge0$显然他们都能达到,我只需要选两个相同的数字即可。
然后考虑$x+2k+1$, $k\ge0$, 其实这里并不一定能达到上届,我们需要更多的分析。考虑这样一个事实,当你选择了$x+2k+1\gt18$的时候,我们一定可以找到更少的数,使得他他们异或和与当前$x+2k+1$个数相等。我们不妨设$f[i]$为精确$i$个数能异或出的最大值,显然$f[i]$可以由$f[j]$转移过来,其中ij之差不会超过18。然后考虑$f[j]$由$f[k]$转移过来,jk只差不会超过18,这里我们可以确定,
如果ij差、jk差都为偶数或者都为奇数,则可以规约于$f[i]由f[k]$转移过来,ik为偶数。
如果ij差、jk差都为一奇一偶,则jk中有且仅有一个数与i之差为偶数,不妨设她为t,则$f[i]$可以有$f[t]$转移过来,it之差为偶数。
综上,当i大于36的时候,$f[i]$可以由$f[i-2]$转移。所以我们fwt暴力计算到36即可。
1 |
|
G Greater and Greater
题意
给你一个长度为n的序列A,和一个长度为m的序列B,你要计算A有多少个子串S,满足$\forall i \in [1,m] S_i\gt B_i$
数据范围
$n<1.5\times10^5$
$m<4\times10^4$
题解
设$01$矩阵$G[i][j]$代表$A[i]\gt B[j]$是否成立。
则我们要计算的其实是G中有多少个斜着的直线,其值全是1。
换句话说,你要计算$bitAnd_{i=0}^{m-1} (G[i]<<i)$, $G[i]$代表矩阵G的第i行所代表的二进制数。
我们同时发现列与列是独立的,所以我们可以对A进行排序,然后对于$G[i]$,显然他是一个左边为0,右边为1的01串,这里我们可以对每一行使用bitset暴力更新,
我们发现行与行是独立的。所以可以分别计算每一行,然后暴力移位使用and运算。
空间复杂度$O(\frac{N}{64}+\frac{M}{64})$
时间复杂度$O(\frac{M\cdot N}{64})$
H Happy Triangle
题意
多重集合,支持三个操作,
插入一个数x
删除一个数x
询问能否在集合中找两个数,和x一起作为边长,能构成三角形。
题解
考虑查询
如果x为最大值,查询他的两个前驱即可。
如果x为中间值,一个前驱加一个后继即可。
如果x为最小值,找到相邻两个数,让他们对差最小即可。
前两个用map,后以后用平衡数。
为了避免map的边界,可以在前后加入哨兵,讨论的时候删除哨兵即可。
J Just Shuffle
题意
给你一个置换P,给你一个数字k,你要计算$P^\frac{1}{k}$
题解
1 |
|