zoukankan      html  css  js  c++  java
  • 【2021~2022】模拟赛乱写 Period II

    发现 (s o t) 的路径是必经的,那么树变成以 (t) 为根

    对于必经路径上的每个点,小 A到这个点的时候有“找一个点对应的子树钻进去”的决策,那先处理在树里面的路径形式:

    (dp_x) 表示在 (x) 子树里面走的最小操作次数,转移显然是上来 小 B 找到 (f_t) 最大的 (t) 毙掉,然后 小 A 钻到次大子树里面,小 B 毙掉根节点其它子树

    那么在链上的路径形态也比较容易刻画,小 A 走到一个子树里面然后 小 B 封锁这个点根链上所有点的出度,再放 小 A 出来

    注意如果在根链之前的点上选择过封锁边了,钻进这个子树的代价要累加

    预处理出来度数前缀和 / (s o t) 所有点非链上子树的代价,考虑二分答案

    检查当前答案是否合法的时候从 (s)(t) 找所有能钻的地方,计算 小 A 是不是钻进去就使次数非法,是则需要提前删除该子树

    如果必须删除子树的操作大于 (s) 到该点的距离,那么该 (mid) 不合法

    时间复杂度 (Theta(nlog n))

    欢乐豆

    由于 (a_i>0),所以对于没有修改出边的点,直接走完全图上的初始边就是最优的,不需要进行松弛

    为了实现方便,将所有边修改涉及的点都叫做弱联通块里面的点

    对于那些存在被修改的边的点,观察这种点 (u) 到其他点的最短路的可能构成

    • 到弱联通块里面的点有走出弱联通块再返回/直接在弱联通块里面走两种选择

    • 到弱联通块外面的点可以花费 (a_u) 的代价走到弱联通块外面的点 (v),再花费 (a_v) 的代价随便走;也可能在弱联通块里面乱走,走到一个比较优的 (w) 点走出去

    注意这里的 (a_v) 一定是取的最小的 (a_v)

    将弱联通块里面的点给一个标号,由于朴素堆优化 Dijkstra 复杂度有边的瓶颈,在完全图有非常大的缺点,那么考虑线段树优化寻找从源点开始最小距离点的过程

    对于每个弱联通块里面的点都进行一个 Dijkstra,初始化叶子上每个点距离为走出再走回的最小距离

    每次松弛操作可以转化为单点取 (min) 和对被修改的两点之间的区间取 (min) ,是线段树的基础操作

    在计算弱联通块里面的点的最短路的时候维护 (dis_x+a_x) 的最小值来表示走出弱联通块时候的最短路即可

    时间复杂度 (Theta(m^2log m))

    混乱邪恶

    (n) 变成偶数,即若 (n) 不是偶数就在序列里面补一个 (0),然后排序

    (d_i=a_{2i}-a_{2i-1}),不难发现 (sum d_ile m-frac{n}2le n),目标是让 (sum d_i=0)

    尝试推导是否存在任意解,不难发现方法是对 (d_i) 的正负号进行调整,同时过程中满足 (forall d_ige 0)

    尝试归纳证明这个有解的结论:设 (nle 2k) 时有解,那么现需要观察 (n=2k+2) 时的情况

    这时可以找到不为 (0) (min d_i)(max d_i) 并将这两组合并,也就是说得到 (min d_i) 的一组内的 (c_i) 一律取反,发现 (d_i) 之和的变化量是 (2min d_i)

    这样子 (nleftarrow n-1),变成了原来的子问题,根据归纳假设,原命题成立

    回到代码实现直接能取反就取反就行了,比说的简单多了

    仙人掌

    观察邻接矩阵行列式的实际含义:找到两个点匹配,每次贡献 (-1) 的逆序对数

    注意每指定两个数匹配的时候行列式必然加一,而图为仙人掌的时候将整张环进行匹配的逆序对数为环长减一

    这是因为可以将环上的数字重新排序并标号,让 (p= m{{len,1,2,dots,len-1}}) 注意到交换两个点标号之后等价于交换一行的同时交换一列,这样子逆序对数正负性不变

    同时环上匹配的时候可以钦定两个方向所以贡献要乘二

    梳理贡献之后是一个套路的仙人掌 ( m{DP}),当然这种东西不容易想出,建出圆方树后分开讨论:

    定义实点,也就是原仙人掌上的点有 (f_{x,0/1}) 表示这个点是不是被匹配了,匹配指作为 (p_i) 出现,对于新建出来的虚点表示 (f_{x,0/1}) 表示点双的根是不是被匹配

    由于在现行圆方树上虚实点交替出现,对于实点的转移直接考虑是不是在这个点双被选中,(f_{x,0}) 则是所有儿子 (f_{t,0}) 的乘积

    对于虚点而言,需要一个子 (dp),注意在环上第一个点和最后一个点的时候计入环顶被选的方案,同时计算 (f_{t,0}) 的乘积来维护环上全选的贡献

    合并实点的时候两两一组,做一个子 ( m{DP}) 即可得到答案

    乘法

    关注到十六进制的后十六位可以使用自然溢出保存,同时可以在 (Theta(log)) 的时间内计算 (n!) 中有几个因子 (2),对 (4) 取余后左移回来即可

    偶数的部分可以先左移再计算,本质上是一个子问题,那么问题转化为:(1 o n) 中奇数的乘积之和,写作下式

    [prod_{i=1}^{frac{n-1}2} (2i+1) ]

    由于是在 (mod 2^{64}) 意义下计算,那么选择 (2i) 的项不能超过 (63) 个,否则直接溢出

    枚举选择了多少个 (2i),将 (2) 因子最后左移加入答案,此时就是计算在 (n) 里面选择 (m) 个数字的乘积,求所有选择方案的和

    直接写出该问题的暴力 ( m{Dp}) 转移式子发现是 (2m) 多项式,直接平方 ( m{Lagrange}) 插值就可以做到 (Theta(Tlog^{4}m)),也可以少一个 (log) (但是前者过了后者没过去是怎么回事呀)

    而其实这个问题的答案使用第一类斯特林数可以表示成:

    [egin{bmatrix}n+1\n-m+1end{bmatrix} ]

    原因是在斯特林数的递推过程中,增加环大小的那些数字 (x)(区别于增加环数量的数字)会贡献 (x-1),将 (nleftarrow n+1) 后就可以得到正确和式

    根据实际含义,环大小不为 (1) 的环非常少,可以 ( m{DP}) 求出:设 (dp_{i,j}) 表示使用 (i) 个数字组成 (j) 个大小大于 (i) 的环,转移是相对简单的,枚举枚举添加圆排列中的数字个数

    实现的时候细节是计算逆元,偶数不存在逆元,奇数的逆元是其 (2^{63}-1) 次方,直接使用欧拉定理可以得到

    斐波

    先记录比内公式:

    [ m{fib_n=frac{1}{sqrt5}[(frac{1+sqrt 5}2)^n-(frac{1-sqrt 5}{2}})^n] ]

    (phi_1 = frac{1+sqrt 5}2,phi_2=frac{1-sqrt 5}2)使用该公式可以将单个 (f(S)) 进行展开:

    [f(S)=frac 15sumlimits_{Tsubset S} [phi_1^{2sumlimits_{xin T} x}-2phi_1^{sumlimits_{xin T} x}phi_2^{sumlimits_{xin T} x}+phi_2^{2sumlimits_{xin T} x}] ]

    稍加以 ( m{GenFunc}) 思想就能知道 (sumlimits_{Tsubset S} phi^{sumlimits_{xin T} x}=-1+prod_{xin S} (phi^x+1))

    也可以组合意义理解:从每个中选一个,也可以不选,最后减去空集情况

    至此本题得到极大简化,那么可以对于每个 (x) 计算 (phi_1^x,phi_1^xphi_2^x) 的值,因为比内公式本身使用无理数表示有理数,那么无理部分必然消成 (0),那么可以不维护 (phi_2^x)(来减小常数因子对程序运行效率的影响)

    回到本题,注意题目并不是求一个 (f(S)) 的值,而是求一个区间的子区间作为 (S) 时的 (f(S)) 值之和,这是一个简单的 ( m{DS}) 问题,可以离线套用古老的序列问题的解法,也可以考虑用如下的线段树做法:

    线段树每个节点维护 ( m{ans,Mult,lsum,rsum}) 表示答案,区间权值乘积,区间内每个前缀的的乘积和,每个后缀的乘积和,合并信息自推不难

    实现的时候可以使用 (asqrt 5+b) 的形式维护复数值,记得重载乘法和不同复数不同之处

    百鸽笼

    将对空格子等概论变成随便找,找到空格子位置为止,此时每列被选中的概率是 (frac 1n),但因为空格子相对于总数量的比例是确定的,两者相乘得到的结果与前者相同

    (G_i(x)=sumlimits_{i<a_i} frac{x^i}{i!}),观察最后得到的序列的形态(不妨设最终是第 (k) 列有剩余格子):

    这时候序列中出现的 (y eq k)(y) 的数量不小于 (a_y) 个,(k) 的数量恰好为 (a_k-1)

    如果枚举最终序列长度不简洁,但是 (e) 的展开式能让式子大为简化,写出序列的 ( m{EGF}) 和用 ( m{EGF}) 表示的答案

    [F_k(x)=frac{x^{a_k-1}}{(a_k-1)!}prodlimits_{i eq k}e^x-G_i(x) ]

    [Ans_k=sum_{ige 0} frac{[x^i]F_k(x)i!}{n^{i+1}} ]

    这里 (i) 枚举的是除去最后一个人得到的序列长度,上面的 (i!) 是多重集排列在使用 ( m{EGF}) 时必要的补充项,分数线下的 (n^{i+1}) 是对应的概率,因为序列长度是 (i+1),指数含义也由此得到

    展开答案,可以表示成 ([e^ax^b]) 的系数和 (e^ax^b) 的乘积的和,其中系数可以通过 ( m{DP}) 得到,设为 (lambda)

    推导单独一个 ([e^ax^b]) 对答案的贡献:

    [frac{lambda}{n^{b+1}}sum_{ige 0}frac{(b+i)!a^i}{i!n^{i}} ]

    [frac{lambda b!}{n^{b+1}}sum_{ige 0}inom {b+i}{i}( frac a{n})^i ]

    后半部分由 (sum_{kge 0}inom{m+k}{k}x^k=frac{1}{(1-x)^{m+1}}) 可以直接化简,至此题目得到 (Theta(n^6)) 的做法,正常写法都可以通过

    但是仍然可以通过先做背包求出所有列对应的多项式系数再在单独求的时候消除贡献(类回退背包状物)将复杂度降至 (Theta(n^5))

    游戏

    分析两人策略能得到:

    • 对于先手而言,如果他想达到这个石子被/不被自己拿走的目的,在该目的达成/最终失败之前,他的目的保持不变,具体而言,如果某时想投一面,那么一直投一面

    • 对于后手而言,如果先手想达到石子被/不被自己拿走,后手为胜利则需要抗拒先手决策,那么先手想拿走,后手要抢,先手弃的子,后手也不能要

    据此定义 (A_i) 表示还剩 (i) 个石子时先手执先时先手胜利概率,(B_i) 表示还剩下 (i) 个石子时,后手执先时先手胜率,转移为:

    设每个石子没有在两次投硬币内拿走的概率是 (R)

    • (A_ile B_i) 时,先手在第 (i+1) 个石子的决策应为拿走该石子,此时 (R=(1-p)(1-q))

    [A_{i+1}=frac{q(1-p)}{1-R}A_{i}+frac{p}{1-R}B_i,B_{i+1}=frac{q}{1-R}A_i+frac{(1-q)p}{1-R}B_i ]

    使用等比数列求和均可以简单求出,观察转移之后的 (A_i-B_i),化简后有 (pqA_i-pqB_ige 0),成功变成了下面的情况

    • (A_ige B_i) 时,先手在第 (i+1) 个石子的决策是放弃该石子,此时 (R=pq)

    [A_{i+1}=frac{p(1-q)}{1-R}A_i+frac{1-p}{1-R}B_i,B_{i+1}=frac{1-q}{1-R}A_i+frac{q(1-p)}{1-R} ]

    再观察得到 (A_i-B_ile 0),那么需要用第一种转移的式子

    两种转移交替进行,直接使用矩阵快速幂优化即可

    Sanrd

    不难发现序列的一个 ( m{LIS}) 和一个 ( m{LDS}) 的交点不超过 (1) 个,设 (f_i) 表示经过 (i)( m{LDS}) 个数,总 ( m{LDS}) 个数为 ( m{all})

    如果一个 ( m{LIS}={p_1dots p_k}) 满足 (sum_{i=1}^k f_{p_i} = m{all}) 那么其跨过所有 ( m{LDS})

    那么可以在求 ( m{LIS}) 的过程中记录两个当前 (f) 之和的值不同的前驱,因为后面转移过程中带来的增量是相同的,所以必有其一合法

    仍然使用数据结构优化这个寻找 ( m{LIS}) 的过程,对于 (f_i) 非常大的事实,直接让其对大质数取模

    关注较大方案存在性常用的手段便是对大质数取模,该技巧也可以运用到一类回退背包问题的解决中

    如何优雅地送分

    观察 (2^{f[i]}) 这一奇怪统计方式,不难发现是一个数集合状物,那么问题直接转化为求解下式:

    [sum_{i=1}^n mu^2(i)lfloorfrac ni floor ]

    考虑展开 (mu^2(i)=sumlimits_{k^2|i} mu(k)),证明考虑实际含义,将 (mu) 函数值不为 (0) 的因子放在集合中便可以看做一个完整的容斥起手式

    [sum_{i=1}^n sum_{k^2|i}mu(k)lfloorfrac{n}i floor ]

    提出 (k) 就非常优美了,记 (S(n)=sumlimits_{i=1}^nlfloor frac ni floor)

    [sum_{i=1}^nmu(i)S(lfloor frac n{i^2} floor) ]

    直接整除分块就行了

    ARC124E

    传出球数最小值不为零时可以将所有人的传球数量减少,因为得到的 ({B}) 序列不变

    观察原式的实际含义:得到序列后从每个人手上选出一个球的方案数

    每个人的球只有两种来源:自己原来没有传出去的球/上一个人传过来的球。启示我们记录球的来源以 ( m{DP})

    下设 (S_k(n)=sumlimits_{i=1}^n i^k)

    状态定义有点奇怪:(dp_{i,0}) 表示第 (i) 个人从自己处选择球且不计第 (i) 个人选择方案时前 (i-1) 个人的选球方案数,(dp_{i,1}) 表示第 (i) 个人从前面人选择球且计入第 (i) 个人选球方案时的方案数

    转移分为 (4) 种情况:

    • ((i,0) o (i+1,0))(i) 个人的选择方案需要被计入,因为下一个人在自己处选择,所以没有 (a_i),剩下几个球就有几个方案,系数为 (sumlimits_{i=1}^{a_i} i=S_1(a_i))

    • ((i,0) o (i+1,1)) 有两个人没有计算,且都在 (a_i) 中选择:(sumlimits_{i=1}^{a_i-1} i(a_i-i)=S_1(a_i)a_i-S_2(a_i))

    • ((i,1) o (i+1,0)) 需要计 (a_i) 个球中有几个传出,系数是 (sumlimits_{i=0}^{a_i}1=1+a_i)

    • ((i,1) o (i+1,1)),和第一个情况类似,系数是 (sumlimits_{i=1}^{a_i} i=S_1(a_k))

    因为是一个环,那么需要在 (1) 处统计答案,这时可以枚举 (1) 的决策是在自己处选择还是在 (n) 个人出选择

    注意这样子统计出来的并不要求传球数最小为 (0) 那么可以再编一个传球数最小为 (1) 的式子写出来即可

    CF1086F

    (f_i) 表示 (i) 权值对应点数,对其做前缀和得到 (g(i)),观察其实际含义得到 (g_i) 表示在 (i) 时刻被标记点数

    至此答案可以被表示成 $ T g_T-sum_{i=0}^{T-1} g_i$

    在每个两个点构成的正方形交之前,点数可以表示成一个二次函数,而在正方形交之后点数扩展量仍逐时间递增,也是二次函数

    所以我们发现 (g_i) 是分段二次函数,每个点值都是矩形面积并,可以简单求出,剩下的任务是分段求出二次函数并求和即可

    时间复杂度 (Theta(n^3log n))

  • 相关阅读:
    Ubuntu16.04下安装virtualbox,配置及卸载
    机器学习1-线性回归
    python中的数据结构-链表
    Numpy 对于矩阵的操作持续更新
    ubuntu16.04 下同时打开多个终端窗口
    matlab mashgrid 函数
    站立会议04
    站立会议03
    第一次冲刺--站立会议02
    第一次冲刺--站立会议01
  • 原文地址:https://www.cnblogs.com/yspm/p/15390029.html
Copyright © 2011-2022 走看看