码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Global Round 7 题解

时间:2020-03-31 01:03:51      阅读:66      评论:0      收藏:0      [点我收藏+]

标签:限制   表示   线段   相等   关系   iss   max   大于等于   递推   

A

一种合法构造方式是\(299\cdots 9\)

code

B

发现每次的\(x_{i-1}\)都是知道的,于是可以直接递推。

code

C

最终答案所选的数一定是\(n-k+1\)\(n\)的所有数。把这些数所在的位置记作\(p_1,p_2,\cdots,p_k\). 不难发现每个\(r_i\in [p_i,p_{i+1})\),于是答案就是\(\prod (p_{i+1}-p_i)\).

code

D

首先把首尾能构成回文的部分删掉,因为这部分一定会出现在答案中。

问题变成了在当前字符串中选取一个前缀/后缀,使其为回文串且长度尽可能长。这个可以使用manacher/hash/回文自动机实现。这里笔者使用的是双hash(欢迎来hack)

code

E

注意到答案是单调不升的,我们可以从大到小扫一遍并判断当前答案是否成立。

考虑对于一个数\(x\)它何时不能成为答案:对于从右往左数的第\(i\)个比\(x\)大或相等的数,其右边至少有\(i\)个炸弹。

我们考虑维护\(b_i\)为位置\(i\)右边大于\(b_i\)的大于等于当前答案的数减去\(i\)右边炸弹的数量。当\(\max(b_i)\leq 0\)时说明当前的答案过大。

\(b_i\)的维护可以使用线段树。

code

F

\(f_s\)是构成串\(s\)的方案数。直接\(f_s\)求显然过于复杂,我们考虑容斥的想法,令\(F_s\)表示构成串\(s\)的数量,其中\(s_i=1\)表示\(p_i\)\(p_{i+1}\)相互认识,\(s_i=0\)表示不限制\(p_i\)\(p_{i+1}\)的关系。不难发现有\(F_s=\sum_{s\subseteq t}f_t\).这样我们可以求出\(F\),之后直接用FWT求出\(f\).

这样转化之后有一个重要的性质:我们可以忽略原串的位置限制,而是将\(n\)个人划分成若干个等价类\(p(1),p(2),\cdots,p(k)\).每个等价类中的所有人需要连成一条链,等价类之间的边会随着当前的串\(s\)而唯一确定。举一个例子:\(F_{1100111}=F_{0111011}\).这个性质的重要之处在于大大压缩了有效状态数,有效状态数为\(n\)的划分数,大致在几百左右。

先考虑一个简单的问题:如何对单个等价类求答案。我们记\(G_s\)表示将集合\(s\)中的人连成一条链的方案数,这个的转移比较简单,记\(g_{s,i}\)为集合\(s\)中的人连成一条以\(i\)结尾的链的方案数,对\(g\)暴力转移之后有\(G_s=\sum_{i\in s}g_{s,i}\).

接下来考虑如何通过\(G\)\(F\)(注意此时\(F\)的下标对应着\(n\)的每一种划分方案).可以把答案写成这样

\[\sum_{\sum_{i=1}^k |p(i)|=n \ \forall i,j\ p(i)\bigcap p(j)=\empty\ }\prod_{i=1}^k G_{p(i)} \]

枚举\(n\)的每一种划分方案,将条件2转化为\(\bigcup p(i)=\{1,2,\cdots,n\}\),这样的话可以直接对\(G\)做一遍\(or\)的FWT来求出\(F_i\).在实现上,可以将原来的\(G_s\)变形为\(G_{|s|,s}\),然后在枚举划分的时候将对应的\(G_{i,s}\)算上即可。

最后枚举\(s\),根据FWT的结果求出\(F_s\),再求出\(f_s\)即可。具体实现可参照程序。

code

Codeforces Global Round 7 题解

标签:限制   表示   线段   相等   关系   iss   max   大于等于   递推   

原文地址:https://www.cnblogs.com/encodetalker/p/12602482.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!