BCPC预赛2020

来随便做做,当作康复训练了
因为都是胡乱扫一眼题面就去做别的事情了
然后用一些零碎的时间想,因此数据范围常常看错
目前做了F,K,M,N,L,H,J

F

一开始看上去非常不可做…
大力猜结论:一定先推完一个再推另外一个
然后被样例打没了
仔细看数据范围都是15
发现可以大力压箱子和人的位置,然后就没了 O ( ( n m ) 3 ) O((nm)^3) O((nm)3)

K

一开始看上去非常不可做
想着枚举r,然后线段树维护每一个l的答案
然后发现并没有任何很好的性质
仔细看数据范围,a,b都小于20
开始大力考虑维护一个 h i h_i hi, g i g_i gi对面有这个数的段的答案和没有的答案
后来发现大力FWT就可以了,先状压每一个牌的状态
先用xor维护出每一段最终状态的方案
最后我们要求这个玩意a&(a^b)的卷积,可以发现等价于a&(!b)
大力AND就可以了

M

先胡乱搞一发
f i f_i fi表示凑出 i i i的乘积划分,因子间顺序无关,就是 2 ∗ 3 2*3 23 3 ∗ 2 3*2 32算两个
f i = 1 + ∑ d ∣ i f ( d ) f_i=1+\sum_{d|i}f(d) fi=1+dif(d)
F i F_i Fi f f f的前缀和
答案就是 ∑ 2 ∗ f i ∗ i ∗ F n / i \sum2*f_i*i*F_{n/i} 2fiiFn/i
发现没法分块,定义 G i = f i ∗ i G_i=f_i*i Gi=fii
考虑直接筛F,不难发现
枚举最后一个填啥
F i = ∑ d F i / d F_i=\sum_dF_{i/d} Fi=dFi/d
考虑筛G,考虑G的意义,然后依然枚举最后一个填啥
G i = ∑ d G i / d ∗ d G_i=\sum_dG_{i/d}*d Gi=dGi/dd
分块套分块的形式,参考杜教筛的复杂度分析可知是 O ( n 2 / 3 ) O(n^{2/3}) O(n2/3)

顺便学习了一波杜教筛,突然发现当年学不会的东西怎么这么好搞的样子。。
先说一下一般形式
假设 S n S_n Sn f f f的前缀和,我们要求 S n S_n Sn
如果不好求,考虑引入另外一个函数 g g g
尽可能满足 f ∗ g = h f*g=h fg=h然后h,g都比较好求,其中 ∗ * 为狄利克雷卷积
大力展开 ∑ i = 1 ( f ∗ g ) ( i ) = ∑ i = 1 ∑ d ∣ i f ( i / d ) ∗ g ( d ) = ∑ d g ( d ) ∑ d ∣ i f ( i / d ) = ∑ d g ( d ) ∑ n / d F ( i / d ) = ∑ i h i \sum_{i=1}(f*g)(i)=\sum_{i=1}\sum_{d|i}f(i/d)*g(d)=\sum_{d}g(d)\sum_{d|i}f(i/d)=\\\sum_{d}g(d)\sum_{n/d}F(i/d)=\sum_ih_i i=1(fg)(i)=i=1dif(i/d)g(d)=dg(d)dif(i/d)=dg(d)n/dF(i/d)=ihi
如果h的前缀和和g的前缀和都很好求就可以大力分块套分块了
以这题为例,考虑推 f f f
∑ d ∣ n f ( d ) A ( n d ) = 1 \sum_{d|n}f(d)A\left(n\over d\right)=1 dnf(d)A(dn)=1
其中A除了 1 1 1 1 1 1,其它都是 − 1 -1 1
A和1的前缀和都非常好求,于是就可以筛了
G的推法也差不多,不写了

所以说,杜教筛和积性函数有啥关系?

顺便说一下 ϕ \phi ϕ的筛法
有一个性质就是 ∑ d ∣ n ϕ ( d ) = n \sum_{d|n}\phi(d)=n dnϕ(d)=n
证明的话可以考虑 1 n , 2 n , 3 n . . . n n \frac{1}{n},\frac{2}{n},\frac{3}{n}...\frac{n}{n} n1,n2,n3...nn的最简分数形式

突然想起来以前出一个一个大力DP题,然后被嘲讽是FWT裸题
这次又搞出一个大力DP题,然后判定为杜教筛入门题
顺带一题,如果K没有反应过来等价关系然后用AND来搞,也可以大力DP…
大概就是确定了前 i i i位然后状态是j的方案数就可以了,复杂度是一样的
FWT_XOR没法救
所以我的技能树怎么一直跟不上时代。。怪不得我这么菜

N(12.12)

距离上一次做这套题已经十天过去了
直接讨论不好讨论,考虑对于每一个引入变量 d i d_i di表示第 i i i个选不选
( ∑ i = 1 n d i a i ) 2 ∑ i = 1 d i a i 2 = 1 + ∑ i = 1 n ∑ j = i + 1 n a i a j 2 d i d j ∑ i = 1 d i a i 2 \frac{(\sum_{i=1}^n{d_ia_i})^2}{\sum_{i=1d_ia_i^2}}=1+\frac{\sum_{i=1}^n\sum_{j=i+1}^na_ia_j2d_id_j}{\sum_{i=1d_ia_i^2}} i=1diai2(i=1ndiai)2=1+i=1diai2i=1nj=i+1naiaj2didj
求后面的最大值就可以了
把后面的式子看作有n*n个物品,然后如果选了物品 ( i , j ) (i,j) (i,j)就必须选 ( i , i ) (i,i) (i,i) ( j , j ) (j,j) (j,j)
分数规划之后
跑一个最大权闭合子图即可
m的限制直接放上去就可以了

L

大力莫队即可

H

最大不说了,考虑最小
先转化一下比较好搞
有n条线段,不能选相邻的,选出k条
一个直观的做法是带后悔的贪心
我是写了两个set来维护,常数太大光荣牺牲,不调了
翻了一下,还有用WQS二分的做法
不提了

这套题怎么全都是技能树?

J

考虑怎么计算答案
我们维护两个值 f i f_i fi, g i g_i gi,分别表示走到 i i i的概率, i i i还能继续走的概率
答案就是 1 + ∑ f i ∗ g i 1+\sum{f_i*g_i} 1+figi
f i f_i fi一开始每一个串的结束点都是 1 / n 1/n 1/n
设一个串的字串个数为 t i = m ∗ ( m + 1 ) / 2 t_i=m*(m+1)/2 ti=m(m+1)/2m为串的长度
然后开始从长到段短更新,每一个串 i i i给他能到的串加上 f i f_i fi,当然乘上 t i t_i ti
g i g_i gi的话就是一个串可以到达的字串个数,当然要记重,最后除 t i t_i ti即可
具体实现的话,把AC自动机建出来
f的话就是fail加,当然每一个前缀节点都要跳,这个的话打个lazy,前缀节点跳的时候一起处理就好了
g的话也是跳fail,然后值要传给每一个后缀节点,同样打一个lazy给后缀节点就可以了
复杂度O(n)
感觉很对的样子,然而WA4了,溜了溜了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值