Atcoder_abc 312 题解

#! https://zhuanlan.zhihu.com/p/658043177

AtCoder Beginner Contest 321

A - 321-like Checker

读入,判断。

B - Cutoff

为了省时间,在数据范围足够小的情况下,我用了 O ( n 2 l g 2 n ) O(n^2lg^2n) O(n2lg2n)的二分。

C - 321-like Searcher

这道题啊,exciting!

我们一眼看上去是一道数位dp。

然后开码,尝试一位一位填,然后,调不出来了。

好吧,算一算,一共1022个数,爆搜啥的搞一搞就行了。我其实知道爆搜能过,就是想打数位dp。

D - Set Menu

这个,two pointers或者二分都可以在线性对数的时间内做出。

E - Complete Binary Tree

点很多的抽象完全二叉树问题,我上次才和大家讨论过(cf 896div2)。

我们可以容斥,像点分治一样…

当然也可以不用,我们分别,算子树内的,子树外的,由于向下算点比较方便,我们可以一边往上跳一边算另一个儿子的对应深度贡献。

1
2
3
4
5
6

比方说, 我们在1算距离为3的,记录 l , r l,r l,r, 表示点的区间,然后 r r r n n n取min, l > n l > n l>n 就返回0。

( 1 , 1 ) → ( 2 , 3 ) → ( 4 , m i n ( 6 , 7 ) ) (1,1) \to (2,3) \to (4,min(6, 7)) (1,1)(2,3)(4min(6,7))

减一减就出来了。

F - #(subset sum = K) with Add and Erase

这道题,就感觉很naive。

每次加入一个数就是背包嘛,减去一个数把这玩意的贡献扣掉,就行了()。

G - Electric Circuit

还是太菜了

简述题意:共N个点,连M条边,要求每次选上部和下部的一个点匹配,并且上下部每个点恰好被选一次,求 M ! M! M!方案中的联通快期望个数。

首先化期望为计数,即 a n s = c n t M ! ans=\frac{cnt}{M!} ans=M!cnt

我们要求cnt.

n ≤ 17 n\le17 n17 很明显的装压,我们要求每个子集构成一个连通块的总次数。

我们考虑这样一件事情。

r ( s ) r(s) r(s) 表示 s s s中的点在上部出现总次数。

f ( s ) f(s) f(s) 表示我们只 s s s点集的点出来连边的总方案数。很显然,如果上下两部 s s s内的点出现总次数不相同,答案是0。否则的话,就是方案就是 r ( s ) ! r(s)! r(s)!

g ( s ) g(s) g(s) 表示我们选 s s s点集的点出来连边,且他们构成一个连通块的方案数。

那么,我们就有 f ( s ) = ∑ s 1 , s 2 . . . s k ∏ k g ( s k ) f(s)=\sum_{s_1,s_2...s_k}\prod_k g(s_k) f(s)=s1,s2...skkg(sk)

即,把集合 s s s划分成一个个独立的连通块,他们的方案数乘积的和就是 f ( s ) f(s) f(s)

如果学过一点卷积,可以看出 f ( s ) = exp ⁡ ( g ( s ) ) → g ( s ) = ln ⁡ ( f ( s ) ) f(s)=\exp(g(s)) \to g(s)=\ln(f(s)) f(s)=exp(g(s))g(s)=ln(f(s))

然后这个方法可以做到 O ( n 2 n ) O(n2^n) O(n2n) 然后这不是我们讨论的范畴(希望有佬帮忙补一下这个坑)

我们考虑,既然我们要求 g ( s ) g(s) g(s), 我们可以把上面的式子拆一下

f ( s ) = g ( s ) + ∑ s 1 , s 2 . . . s k ∏ k g ( s k ) , k > 1 f(s)=g(s)+\sum_{s_1,s_2...s_k}\prod_k g(s_k),k>1 f(s)=g(s)+s1,s2...skkg(sk),k>1

移项

g ( s ) = f ( s ) − ∑ s 1 , s 2 . . . s k ∏ k g ( s k ) , k > 1 g(s)=f(s)-\sum_{s_1,s_2...s_k}\prod_k g(s_k),k>1 g(s)=f(s)s1,s2...skkg(sk),k>1

稍微化一下

g ( s ) = f ( s ) − g ( s ‘ ) f ( s \ s ‘ ) g(s)=f(s)-g(s`)f(s\backslash s`) g(s)=f(s)g(s)f(s\s)

这玩意就是枚举 s s s子集,然后搞一搞就行了。

复杂度,即枚举子集 O ( 3 n ) O(3^n) O(3n)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值