zoukankan      html  css  js  c++  java
  • 4月训练题解合集

      由于我太懒了,所以就不每题开一篇写了。题目大意也懒得写了。

    DAY1

    1A

      显然最优策略是瞎走,在知道那条边断掉了之后才走最短路径。

      先把以 (T) 为根的最短路树求出来,然后可以用堆求出断掉每条边后端点到 (T) 的最短路径。

      最后像 dijk 那样 DP 一下就好了。

    1B

      直接线段树 + 凸包优化 DP 可以轻松做到 (O(nlog n))

      用 这个方法 可以优化到 (O(n))

    1C

      不同的环长只有 (O(sqrt n)) 种。

      对每种环长算一下答案即可。

    DAY2

    2A

      直接缩个点然后每个出度为 (0) 的连通块扔掉最小值即可。

    2B

      用 这个东西,用平衡树维护序列即可。

    DAY3

    3A

      如果可以修改一个 (a_i) 满足 (forall i,a_{i+1}<a_i+b_i or a_{i+1}>a_i+c_i),那么那一个人第一天就会发现。

      如果可以修改两个,那么那两个人第二天都会发现。

      现在就是要修改最少的 (a_i) 满足上面那个东西。

      可以 DP。枚举上一个没有修改的 (j),那么要求 ([a_i-B_{i-1},a_i-C_{i-1}]subseteq[a_j-B_{j-1},a_j-C_{j-1}])。其中 (B,C) 分别是 (b,c) 的前缀和。

      可以发现区间长度是单调的。

      然后按 (a_i-B_{i-1}) 排序求个 LIS 即可。

    3B

      直接重链剖分然后在重链上二分是 (O(nlog^2n)) 的。

      在重链上从下往上的求轻子树的答案。

      当遇到一个轻子树答案为 (0) 时,这条链上面的答案就都是 (0) 了。

      这样就只用二分下面那部分了。

      复杂度应该是 (O(nlog n)) 的。

    3C

      先二分答案 (s)

      弄一个网格,把 (a_i+b_jleq s) 的部分染白,剩下的部分染黑。

      那么就是你一开始在 ((1,1)),每次找一个同行或同列的异色的点走过去。

      如果 ((1,1)) 在所有最大匹配上,那么先手必胜。

      然后把最大匹配换成最大独立集。

      把 (a_i,b_j) 排序后,选的一定是 (ileq R,jleq C)的白色部分和 (i>R,j>C) 的黑色部分。

      可以发现,当 (R) 变大的时候,(C) 变大的收益是单调的,(C) 也是单调的。

      直接扫一遍就好了。

    DAY4

    4A

      先让每个点能匹配 (k) 条边跑一边网络流。

      然后每次把度数 (=) 度数最大值得点找出来,找一个覆盖这些点的匹配。

      重复 (k) 次即可。

    4B

      记 (f_{i,j}) 为长度为 (i),zjt 在 (j) 处的期望答案。

      显然 (f_{i,1}=f_{i,i}=i)

      设 (f_{3,2},f_{4,2},ldots,f_{m,2})(m-2) 个未知数,每次可以通过 (f_{i,j}) 推出 (f_{i+1,j+1}) 的式子。

      最后把 (f_{m,2},f_{m,3},ldots,f_{m,m-1})(m-1) 个式子拿出来消元即可。

    4C

      分块分类讨论或者树套树都能过。

    DAY5

    5B

      对于每一个 (ileq n),新建一个点 (i')

      连边 ((i,i'))

      对于每一组 ((i,j)),连边 ((i',j))

      答案为最大匹配 (-n)

    5C

      用一棵平衡树维护当前所有最优解以及最优解的答案

      每次遇到一个新的 (a_i) 时,先把当前所有最优解的答案加上 (a_i) 的贡献。

      还有一种情况,就是最优解到 (a_i) 时值为 (a_i-1)

      那就拿之前的最优解平移一下即可。

      这样就能找到之前所有位置都做了最优操作的解(如果不是最优操作,就不会成为最大值)。

    DAY6

    6A

      可以发现,最优解的 (C) 一定是 (P-w_i-1)(T)

      把这些值拿出来每个二分答案 DP 一下就是 (O(n^2(-log epsilon))) 的了。

      这个做法的瓶颈在于二分答案。

      但是我们可以把这些 (C) 值 shuffle 一下,每次遇到一个 (C)(O(n)) 判断答案是否大于上一个,大了再二分,这样就只用求 (O(log n)) 次答案了。

      复杂度是 (O(n^2+nlog n(-log epsilon)))

    6B

      可以发现,(f(a_1,a_2,ldots,a_n)=2^{n-1}(a_1or a_2orcdotsor a_n))

      然后 (n>2) 的答案和 (n=2) 的答案是相同的。

      然后人类智慧手玩一下就好了。

    6C

      按颜色的出现次数分块分类讨论就好了。

    DAY7

    7A

      答案肯定是某一个 (A_i) 再乘上其他的 (B_i) 再加起来的形式。

      枚举 (A_i),那么假设其他的 (B_i) 选了 (k) 个,那么贡献就是 ([x^k]prod_{j eq i}((1-B_i)+B_ix)),对应的方案数就是 (frac{1}{k+1}inom{n}{k+1})

      显然可以分制 NTT。

      把这些加起来之后除以 (n!) 就是答案了。

    7B

      枚举 (i),计算选的数都是 (i) 的倍数的答案。

      设值域为 (m)

      先计算可以重复选的方案数。

      弄一个阈值 (S)(ileq S) 时直接 FWT,复杂度为 (O(mlog m))(i>S) 时直接暴力 meet in the middle,复杂度为 (O((frac{m}{i})^2))

      然后容斥一下就好了。

      取 (S=sqrt{frac{m}{log m}}) 时有最优复杂度 (O(msqrt{mlog m}))

    DAY8

    8B

      考虑种了 (i) 棵不同的树后没有结束的概率。设 (x_i) 为 第 (i) 棵树到下一棵的距离。随便钦定一棵树为第一棵。

      结束了的情况数是 (x_1+x_2+cdots+x_k=n(1leq x_ileq 2)) 的解数,为 (inom{i}{n-i})

      总的情况数显然是 (x_1+x_2+cdots+x_k=n(1leq x_ileq n)) 的解数,为 (inom{n-1}{i-1})

      需要期望 (frac{n}{n-i}) 步才能种下第 (i+1) 棵不同的树。

      所以答案就是 (sum_{i=0}^{n-1}frac{n}{n-i}(1-frac{inom{i}{n-i}}{inom{n-1}{i-1}}))

    DAY9

    9A

      考虑计算逃不出去的概率。

      记 (l=frac{180^circ}{360^circ- heta}) 为半圆占可选区域的比例。

      概率就是在一个长度为 (1) 的环上,随机选 (n-1) 个点,使得存在两个点之间的距离 (>l) 的概率。

      那么可以钦定一个很小区域里面有至少一个点,右边 (l) 的部分没有点。

      答案就是

    [egin{align} &1-frac{1}{h}({(1-l)^{n-1}}-{(1-l-h)^{n-1}})\ =&1-(frac{mathrm{d}}{mathrm{d}x}x^{n-1})|_{1-l}\ =&1-(n-1)(1-l)^{n-2}\ =&1-(n-1)(frac{180^circ- heta}{360^circ- heta})^{n-2} end{align} ]

    DAY10

    10A

      前几天刚刚做过一道基本上一样的题。

      不写了。

    10B

      假设不考虑拿完的影响,算出第一个人在每个时刻的石子数 (s_i)

      记两个人的石子总和为 (S=x+y)

      对于一个区间,如果右半部分的 (max s_i-min s_i) 也就是极差 (geq S),说明左半部分是没有用的,因为到右边还是会取完。

      否则可以轻松地根据左半部分的答案和右半部分的 (min,max) 计算出整个区间的答案。

      每次暴力在线段树上跳即可。

    DAY11

    11A

      直接状压 DP 即可。

    11B

      先差分一下

      那么每次就是选两个差为奇质数的位置,把这两个点的值都取反。

      如果两个位置的差是奇质数,只用一次就可以把这两个位置处理掉。

      如果两个位置的差是偶数,只用两次就可以把这两个位置处理掉。

      剩下的情况只用三次就可以处理掉。

      跑一个二分图最大匹配即可。

    DAY12

    12A

      用一行的未知数表示剩下其他位置,然后高斯消元即可。

      时间复杂度:(O(m^3))

    12B

      先按时间分值把删除去掉。

      对于一个询问 ((x,y)),把横坐标 (leq x) 的点的凸包求出来,那么答案显然在凸包上。

      暴力二分的复杂度是 (O(nlog^2n)) 的。

      注意到这题只用求答案的最小值。

      那么如果凸包最下面两个点连成的直线的斜率 (leq ans),那么最下面那个点很明显是没用的。

      这样不断删点就可以不用二分了。

      复杂度是 (O(nlog n))

    12C

      考虑对每个字符串分开计算答案。

      那么就需要处理两个操作:

       1.在这个字符串后面加上一个字符串

       2.查询当前字符串在 (S) 中的出现次数。

      把修改操作加上的字符串记作 (T)

      把 (S)(T) 放在一起建 SA。

      维护当前符合要求的字符串的 rk 范围,每次加字符串就在这个范围内二分即可。

      复杂度是 (O(n+qlog n))

    DAY13

    13A

      不同的线段树区间长度可能只有 (O(log n))

      就你每一层的长度都是相邻两个整数,然后下一层的也是。

    13B

      可以列出DP方程:

    [f_i=sum_{j=l}^i[b_{j-1}=0]f_{j-1}(i-j+1)^2\ =sum_{j=l-1}^{r-1}[b_{j}=0]f_{j}(i-j)^2\ =sum_{j=l-1}^{r-1}[b_{j}=0]f_{j}(i^2-2ij+j^2)\ ]

      分开维护

    [S2=sum_j (i-j)^2f_j\ S1=sum_j (i-j)f_j\ S0=sum f_j ]

      然后每次转移的时候

    [S2'=S2+2S1+S0+S2\ S1'=S1+S0+S2\ S0'=S0+S2 ]

      这样就好了。

      然后这些矩阵都是可以求逆。

      预处理一下就好了

    13C

    [sum_{i=1}^nsum_{j=1}^nvarphi(ij)dist(i,j)\ =sum_dfrac{lvertmu(i) vert}{varphi(i)}sum_{dmid i,dmid j}varphi(i)varphi(j)dist(i,j) ]

  • 相关阅读:
    [BUUCTF]REVERSE——rsa
    windows下python3.7安装gmpy2、Crypto 库及rsa
    [BUUCTF]PWN——wustctf2020_getshell1/2
    [BUUCTF]PWN——bbys_tu_2016
    [BUUCTF]PWN——xdctf2015_pwn200
    [BUUCTF]REVERSE——[GXYCTF2019]luck_guy
    [BUUCTF]REVERSE——简单注册器
    [BUUCTF]PWN——pwnable_orw
    [BUUCTF]REVERSE——findit
    [BUUCTF]PWN——jarvisoj_level1
  • 原文地址:https://www.cnblogs.com/ywwyww/p/10671098.html
Copyright © 2011-2022 走看看