• 2020-08-12 题目题解


    HOT-Hotels

    题目传送门

    题目大意

    给出一个 (n) 个点的树,问有多少个三元组 ((x,y,z)) 满足 (x,y,z) 两两之间距离相同。

    (nle 10^5)

    思路

    不难想到一个 dp 做法,我们可以设 (f_{u,i}) 表示以 (u) 为根的子树内距离 (u) 距离为 (i) 的点的个数, (g_{u,i}) 表示以 (u) 为根的子树内,二元组 ((x,y)) 满足 ( ext{dis}(x, ext{lca}(x,y))= ext{dis}(y, ext{lca}(x,y))= ext{dis}(u, ext{lca}(x,y))+i) 的个数。

    可以得到转移式:

    [ansgets sum_{i=0}g_{u,i}f_{v,i-1}+g_{v,i+1}f_{u,i},s.t. vin son_u ]

    [f_{u,0}gets 1,f_{u,i}gets f_{v,i-1},s.t. vin son_u ]

    [g_{u,i}gets f_{u,i}f_{v,i-1},g_{u,i}gets g_{v,i+1},s.t. vin son_u ]

    然后我们发现这个东西其实是 (Theta(n^2)) ,但是我们使用长链剖分就可以做到 (Theta(n)) 了。

    ( exttt{Code})

    代码戳这里打开

    Shrinking Tree

    题目传送门

    题目大意

    给出一个 (n) 个点的树,每次可以将一条边连接的两个点合为一个点,新点的编号随机成为两个点编号中的一个。问对于每个 (i) ,最后合完的点编号为 (i) 的概率。

    (1le nle 50)

    思路

    神题啊!不过为毛可以取模还非要卡精度啊?非常费解。。。

    首先,我们可以发现如果我们钦点一个点为剩下来的点,那么,每次当该点与其它点合并的时候都只能保留该点。考虑 dp ,我们可以设 (f_{u,i}) 表示以 (u) 为根的子树内还剩 (i) 条边且当前 (u) 的编号已经变为根的编号最后合并下来留下根的编号的概率(不要问我为什么,我只能告诉你网上大部分资料已经删除干净了,只能说懂得都懂),我们可以得到转移式:

    • 对于 (vin son_u,j<i)

    我们有转移式: (f_{u,i}gets dfrac{1}{2} imes f_{v,j})

    这是因为以 (v) 为根的子树里面当删到只有 (i-1) 条边的时候我们的 (u) 已经被替换成了根的编号了,接着我们的 (v) 子树继续删边直至只剩下 (j) 条边,然后合并 (u,v) ,而它有 (dfrac{1}{2}) 的概率留下 (u) 的编号(即根的编号),然后我们继续考虑 (f_{v,j}) 。所以贡献就是 (dfrac{1}{2} imes f_{v,j}) 。很显然这种计算方法枚举了在多久合并 ((u o v)),所以不会算重。

    • 对于 (vin son_u,j=i)

    我们有转移式: (f_{u,i}gets (size_v-i) imes f_{v,i})

    这是因为 (u o v) 肯定需要删掉,而它删掉的时间却并不固定,我们可以在删掉 (v) 子树内需要删掉的边的过程中删掉该边,与上面不同,我们并未确定 ((u o v)) 在多久合并,而它又有 (size_v-i) 种方法。同时我们发现此时 (u) 的编号并未变为根,所以在合并的时候我们并不关心谁会留下来,因为我们可以之后让根侵占该点。所以贡献即为 ((size_v-i) imes f_{v,i})

    但是我们还需要考虑如何合并两棵子树,可以得到转移式:

    [f_{u,i+j}gets f_{v1,i}f_{v2,j}inom{i+j}{i}inom{v1-i+v2-j}{v1-i},s.t. v1,v2in son_u ]

    这是因为删掉的边可以随意混合,保留的边也可以。

    最后的答案就是 (dfrac{f_{i,n-1}}{(n-1)!})

    于是,我们就可以做到 (Theta(n^4)) 了。

    ( exttt{Code})

    代码戳这里打开

    Fake bullions

    题目传送门

    题目大意

    (n) 个黑帮,每个黑帮有一些人,这些人里面有些有真金条,有些没有金条,并且黑帮之间的关系构成了一个竞赛图。然后黑帮之间发生了一些奇奇怪怪的交易,于是在时刻 (i) ,如果存在 (u o v) 的边,并且黑帮 (u) 中的 ((imod {siz_u})) 有金条(不分真假),并且黑帮 (v) 中的 ((imod{siz_v})) 没有金条,那么,黑帮 (u) 中的人就会凭空造出一个假金条给黑帮 (v) 里面那个人。

    现在,在经历了无限个时刻之后,黑帮们要去卖金条了,假金条可能卖得出去,真金条一定卖得出去,现在要从卖出金条最多的 (a) 个黑帮里面随机选 (b) 个,问有多少种可能选出的集合。

    (nle 5000),黑帮成员总和 (le 2 imes 10^6)

    思路

    所以谁能告诉我这道题为什么评分是 (3400) 啊?

    首先不难看出:出题人是个屑 这是一个强行二合一的题目,我们可以拆成两个部分:

    • 在经历了无限个时刻之后每隔黑帮的真假金条个数

    • 最后如何统计答案并且不会算重!!!

    我们首先考虑解决第一个问题,我们发现如果存在 (iequiv jpmod{gcd(siz_u,siz_v)}) 那么黑帮 (u) 里面的人 (i) 就可以给黑帮 (v) 里面的人 (j) 假金条,具体证明可以使用裴蜀定理证明。

    然后我们考虑强连通分量缩点,那么,一个强联通分量所有 (iequiv jpmod {gcd(siz_1,siz_2,...)})(j) 都可以对 (i) 产生贡献(如果 (j) 有金条的话)。于是我们只需要考虑强连通分量之间的关系,因为缩点之后的图依旧是一个竞赛图,于是我们可以考虑 topo 排序,然后你就发现每个连通分量只对后面的点产生贡献,而且一定能够产生贡献。然后知道一个强联通分量的金条个数,那我们就可以知道每个黑帮的金条个数。

    考虑第二个问题。我们发现,如果我们如果钦定某一个黑帮恰好为第 (a) 个,我们就不会算重,于是我们直接统计一定比它大,以及可能比它大的黑帮个数即可,然后组合数算一下就好了。

    ( exttt{Code})

    代码戳这里打开

    Shuffle and Swap

    题目传送门

    题目大意

    给出两个长度为 (n)(01)(A,B) ,两个串里面 (1) 的个数都是 (k) ,我们把两者位置为 (1) 的位置提出来,分别即为 (a_{1,2,...,n},b_{1,2,...,n}),然后将两个序列随机排序 (( ext{random-shuffle})),按 (1 o k) 的顺序交换 (A_{a_i})(A_{b_i}),问最后 (A) 变为 (B) 的概率。

    (nle 10^4)

    思路

    不管你信不信,空间可以开到 (Theta(n^2))

    首先我们需要转换一下题意:如果存在 (i,j) 使得 (A_i=1) 并且 (B_j=1) ,那么我们就可以交换 (A_i)(A_j) ,问操作 (k) 次后 (A=B) 的概率。

    我们可以称 (A_i=1wedge B_i=1) 的点为“中间点”,(A_i=1wedge B_i=0)的点为“初始点”,(A_i=0wedge B_i=1) 的点为“终结点”。很显然的是,我们可以通过交换初始点和中间点,再交换至终结点,那么我们最后就可以满足条件,于是,我们可以考虑设 (f_{i,j}) 表示用了 (i) 个中间点, (j) 个初始点的合法方案数,我们可以得到转移式:

    [f_{i,j}=i imes j imes f_{i-1,j}+j imes j imes f_{i,j-1} ]

    解释一下,显然从 (f_{i-1,j}) 转移过来其实就是加入一个中间点,显然可以加入在 (j) 个由中间点和初始点的链,同时,我们可以与已经加入的点进行交换,所以有 (i imes j) 种方法。后面那个显然就是加入一个初始点,而我们显然可以新建一个链,同时链也可以交换所以乘上 (j) ,然后同时我们还可以选择一个终结点与它结合,又可以乘上 (j)

    然后我们最后可以考虑枚举有多少个中间点不用就可以算出答案,具体见代码。

    ( exttt{Code})

    代码戳这里打开

    [Lydsy2017省队十连测]好题

    题目传送门

    题目大意

    给出一个 (n) 个点的树,以及常数 (k),每个点都带有颜色,求最小的连通块大小,使得该连通块包含至少不同 (k) 种颜色。

    (nle 10^4,kle 5)

    思路

    我们发现这个 (k) 十分的小,于是,我们不难想到,这道题要么是状压dp,要么就是随机化乱搞。但是这个 (n) 又这么大,所以我们考虑后者。

    我们可以考虑到,如果我们钦定选哪几种颜色,那我们就可以用树上状压dp解决这个问题,时间复杂度 (Theta(tn4^k)) ,其中 (t) 是尝试的次数。

    然后我们就发现这种方法的正确率非常小,大概是 (1-(1-dfrac{k}{n})^t) ,这道题的话我们 (t) 最多取到 (100) 左右,正确率 (approx 4.878246975\%),显然我们需要正确率更高的算法。

    有一种方法,就是将每一种颜色随机映射到 ([1,k]) 中的某个数。我们考虑计算这种方法的正确率,我们发现我们这种方法算出错误答案的唯一情况其实只有正确方法的两种不同颜色被分配到了同一种颜色,正确的概率也就是 (dfrac{k!}{k^k}approx 0.0384),那么随机 (t) 次正确的概率就是 (1-(1-0.0384)^tapprox 98.007283\%),足以通过这道题了。

    不过经过尝试,似乎在随机情况下,(t=20) 也可以通过。(伦敦雾

    ( exttt{Code})

    代码戳这里打开

  • 相关阅读:
    Scoket简介
    AOP
    Windows服务
    Nginx 教程 (1):基本概念
    异步编程
    并发编程
    常用排序
    序列化
    MSBuild/Projectjson
    不汇报是职场发展的绊脚石
  • 原文地址:https://www.cnblogs.com/Dark-Romance/p/13497026.html
Copyright © 2020-2023  润新知