Codeforces Round #833 (Div. 2)
A.The Ultimate Square
题意:你有n个长方体,每个长方形的高为1,宽为 ,你可以选择一些长方形拼成一个正方形,使得正方形的边长最大,求最大边长
思路:手玩几组样例后发现,最大长度就是

B.Diverse Substrings
题意:定义一个字符串是好的,即数字字符种类数大于等于所有数字字符中出现最多的次数,求字符串的所有子串中有多少个字符串是好的
思路:首先数字字符一共只有10种,那么极限情况下10种字符各出现10次也就是100个字符,也就是说这个子串如果是好的,那么长度最长为100,那么就可以暴力了

C. Zero-Sum Prefixes
题意:定义某个前缀是好的,即这个前缀和为0,对于每个的位置,可以将它们变成任意的数字,求最大有多少个前缀是好的
思路:如果让加上
,即代表
的每个位置都加
,如果此时有
,先减去
,再让其加上
,也就是说其实两次操作只在
加上了
,那么对于
,我们就只用考虑
这个区间了(因为操作
,可以让操作
时对
的影响消失),那么我们只用统计
到
这段区间里的前缀和出现次数最多的数,让
变成这个数字的相反数即可

D.ConstructOR
题意:给出a, b, d,求x,使得 (a | x) % d == 0 && (b | x) % d == 0
思路:首先,如果a末尾连续0的个数小于d末尾连续0的个数,那么一定是无解的,假设d末尾连续0的个数为k,那么d一定含有这个因子,而a一定不含,or操作后的数也一定不含,则无解,b也是同样的道理
接下来考虑如何构造一个d的倍数,首先考虑,如果当前x这一位为1,那么or操作之后这一位一定也为1,所以可以不用考虑,如果这一位为0,那么or之后的结果就取决于a或者b这一位为1还是0了,那么我们考虑把这一位变成1,并且变的过程中保持x为d的倍数就可以了,既然要是d的倍数,那么一定用d来变这一位,那么我们可以考虑用d的最低位为1的那一位来填充,具体来说就是 x += d << (i - k);,即把k这个数字左移i - k位,让他的末尾1与这一位1对其,这样构造出来一定是d的倍数,并且a | x = b | x。

