2019.11 月赛题解

Xiejiadong edited 4 年,2 月前

前排广告位

EOJ Monthly 招募贴

花絮

# Tag Idea Developer Tester
A 模拟 Xiejiadong Xiejiadong 10185101232 Grunt
B 数学 暴力 哈希 Xiejiadong Xiejiadong 10185101232 Grunt
C 组合数学 Grunt Grunt 10185101232 Xiejiadong
D 简单多项式计算 Xiejiadong Xiejiadong 10185101232 Grunt
E 筛法 Weaver_zhu Weaver_zhu 10185101232

Problem A

First Solved:gyz_gyz

签到题。

特意固定了 k 的大小,也就是每一位可供选择的字符数量相同。

如果按照字典序的顺序对每一个字母进行 0,1,,k1 编号的话 ,可以发现,题目转换成了 k 进制的转换问题。

根据给出的 x ,从后往前依次确定每一位的大小。

Comments

Xiejiadong :如果转换成了进制转换的模型,根本不会出线乘法运算,所以也不可能会出现爆 long long 之类的问题。

Problem B

First Solved:emengdeath

首先可以发现的是 k 很大是毫无意义的事情。

首先我们考虑等价类的划分问题。

如果我们认为相同的字母都属于同一个容器的话,那么相当于把最多 8 个字母放入若干个相同的容器中,可以发现这是第二类斯特林数的模型。

我们知道 S(8,x)(0x8) 最大是 S(8,4)=1701

也就是说,等价类划分的关系,最多只有 1701 种情况,于是可以考虑枚举所有的等价类划分的情况。

对于已经确定的等价类划分,我们现在需要做的无非就是判断有多少个字符串是等价的。

这部分可以通过字符串 Hash 来实现,直接暴力的字符串 Hash 需要每一次重新计算每一个字符串对应的 Hash 值,是无法通过这道题的。

因为这里最多只有 8 个字母,我们可以考虑预处理每一个字符串中每一个字母所在的位置对应的 Hash 值。

因为每一次都是不同字母之间的全部替换,所以这样每一次计算每一个字符串 Hash 的代价变成了 O(8) ,就可以卡通过此题了。

Comments

Xiejiadong :一开始的 idea 是想做所有字母映射的等价。想了很久发现自己不会做。后来发现字母集改小就可以做了,而且似乎思路挺妙的。

oxx1108 : 感觉这个得和出题人心灵相通才能做吧。

Xiejiadong :那我时限放宽一些,看看有没有各种不同的方法卡过去。

Problem C

First Solved:DeaphetS

链的版本

注意到题面要求的其实是一个”环的版本”,正常想法是先给出“链的版本”的做法,即去掉“12n 不能同时取”的约束,答案记为 f(n,r,s)

[2n] 分为 n 对,分别是 (1,2),(3,4),,(2n1,2n),易知对于任意对 (2k1,2k),有三种可能的情况:

  1. 奇对。选 2k1,不选 2k
  2. 偶对。选 2k,不选 2k1
  3. 空对。2k2k1 都不选。

因为禁止相邻对,所以禁止一个偶对后面紧跟着一个奇对。已知有 r 个奇对和 s 个偶对,则有 nrs 个空对,这些空对把长度为 n 的对串分成了 nrs+1 段,每段内部只有奇对和偶对(可能为空)。考虑每段内部,由于禁止一个偶对后面紧跟着一个奇对,排列方式一定是所有的奇对在左边,所有的偶对在右边,有用的信息只有奇偶对的个数。至此可以做一个集合到方程组解的一一映射,其中 xi0 表示第 i 段的奇对数,yi0 表示第 i 段的偶对数,方程组如下:
$$
\left{
x1+x2++xnrs+1=ry1+y2++ynrs+1=s
\right.
$$
显然两个方程是独立的,f(n,r,s)=(nrs)(nsr)

环的版本

记环的版本的答案为 g(n,r,s),给出两种不同的解法。

容斥,显然 f(n,r,s)>g(n,r,s)f(n,r,s) 多出的部分是恰巧同时选了 12n,这部分其实就是 f(n2,r1,s1),故
g(n,r,s)=f(n,r,s)f(n2,r1,s1)=(nrs)(nsr)(nr1s1)(ns1r1)=(1+rs(nr)(ns))(nrs)(nsr)=n2snrn(nr)(ns)(nrs)(nsr)
Double counting,从两个方向数有序对 (A,E) 的数量,其中 A 是一种子集取法,遍历 g(n,r,s) 的所有解,EA 中空对的编号,共有 nsr 个可能的取值,考虑先枚举 A 还是先枚举 E,可得
(nsr)g(n,s,r)=nf(n1,s,r)g(n,s,r)=nnsr(nr1s)(ns1r)=n(nsr)(nsr)(nsr)(nr)(ns)(nrs)(nsr)=n2snrn(nr)(ns)(nrs)(nsr)
注意特判边界情况。

Comments

Grunt :本题出自笔者修的一门组合数学课的课后作业,感觉这个问题和做法都很有意思,就稍微加强了下,搬运过来。

Problem D

First Solved:ldxxx

比较简单的多项式运算。

假设特殊点的权值分别是 a1,a2,ak ,非特殊点的权值分别是 b1,b2,bm ,显然 k+m=n

我们把边氛围分为三类:

于是我们可以通过总的边权减去非特殊点之间的边权得到。

总的边权

a1a2+a1a3++a1ak+a1b1+a1bm+=12[(a1++ak+b1++bm)×(a1++ak+b1++bm)(a12+ak2+b12++bm2)]

于是,通过计算所有点权的和以及平方和就可以得到总的边权。

非特殊点与非特殊点之间的边的边权

与上面类似

b1b2+b1b3++b1bm+b2b3=12[(b1+b2++bm)×(b1+b2++bm)(b12++bm)]

剩下的问题就是计算原本环上存在边的边权。直接枚举环上的每一条边是否属于非特殊点与非特殊点之间的边,如果是则加上这条边的边权,否则已经存在则不再做计算。

Problem E

First Solved:poorwill

先考虑莫比乌斯反演

F(x)=a1ak[(a1,,ak,n)==x]

G(x)=x|dF(x)={(nx)kx|d0otherwise

我们要求的 i=1nH(i)

H(n)=F(1,n)=d|nμ(d)(nd)k=μnk

i=1nH(i)=i=1nd|iμ(d)(id)k=d=1nμ(d)i=1n/dik

幂方和可以用伯努利数预处理 O(k2),然后 O(k) 求值。

其余用上数论分块和杜教筛求 μ

复杂度 O(n23+kn)

Comments

Weaver_zhu :很没意思的一道题,和多校的一道题套路也重的比较多。

Xiejiadong :两个月前的月赛囤下来的题目。由于没有什么好的 idea 所以就放上来了。

恭喜 DeaphetS emengdeath interestingLSY 分别获得冠亚季军。

Comments

interestingLSY

好题,为良心出题银点赞!

Xiejiadong

蟹蟹支持 刘队nb

卡题卡常卡精度

请问怎么枚举等价类划分啊蒟蒻不会写……

kimoyami

预处理暴力跑出所有情况,然后判断那些是等价类,去重吧

interestingLSY

(小声哔哔)是不是可以打表啊

interestingLSY

我的写法就是 BFS,从 ah 依次考虑,同时维护

  • 总共有几个等价类
  • 每个等价类中都有啥

每次新加入一个字母的时候,有两种情况

  • 新开一个等价类
  • 将这个字母加入到之前的某一个等价类中

与第二类斯特林数的递推思想类似

无须去重(因为根本不会重复)