• 2022 训练实录


    22-06-24

    NOIO2020 #2 游戏

    好久没搞 OI 真的蠢了。

    恰好立刻转至少,所以设 \(f(x)\) 为钦定 \(x\) 对非平局回合的情况,\(g(x)\) 为恰好 \(x\) 对非平局回合的情况。那么:

    \[f(x)=\sum^m_{i=x}\binom i n g(i) \]

    应用二项式反演有:

    \[g(x)=\sum^m_{i=x}(-1)^{i-x}\binom i n f(i) \]

    剩下的问题就是求出 \(f(x)\),套路的,设 \(f_{u,i}\) 表示在以 \(u\) 为根的子树内已经选出 \(i\) 对的方案数,树形背包转移即可,记得考虑选 \(u\) 的方案。

    时间复杂度 \(O(n^2)\),评价:Common。Link

    APIO2022 排列

    优质题,很可惜不懂正解。

    考虑几个乱搞,第一个是直接丢不相交的若干个单调递增序列上去,但是似乎不怎么优秀,第二个是考虑二进制拆分,考虑添加进来的丢前面还是丢后面,似乎可以有 \(90+\)

    考虑优化第二种做法,或者说,我们继续乱搞。首先将这个做法进行劣化,比如说我们考虑每一次添加都使现在的上升子序列增加的尽可能多但是不要让他爆掉 \(k\),可以考虑利用 DP,\(\displaystyle f_i=1+\sum_{a_j<a_i} f_j\),暴力维护这个 DP。

    这个做法也足够优秀,但是仍然没有满分潜质,考虑随机化,因为每一步如果都拉满反而容易达不到效果,随机地看需不需要随机地取一个更劣的结果就行了。

    启示:一个做法烂记得别抛弃它,万一搞了个随机化就莫名其妙过了呢。

    评价:Great。Link

    APIO2022 游戏

    牛逼题,大概自己研究了 1h,然后看题解理解了 1h。

    显然的是,考虑维护一个 \(pre_i\) 表示最大的可以来的传送器,\(suf_i\) 表示最小的可以到的传送器,当一个非特殊点的 \(pre_i\ge suf_i\) 时,成环。暴力地进行搜索可以在 \(O((n+m)k)\) 的时间复杂度内解决问题,获得 \(60\text{pts}\),想到这里就想不动了。

    考虑优化,这里很难想到的是将 \((pre_u,suf_u)\) 看成一个区间,同时注意到不用实时维护 \(pre_i,suf_i\) 而是只需判断。考虑一条新边 \((u,v)\),提取出 \(u,v\) 分别对应的区间,根据这两个关系讨论:

    • 相离,仅当区间 \(u\) 在区间 \(v\) 右边时找到环,此时存在一个 \(pre_u\to u\to v\to suf_v \to pre_u\) 的环。

    • 重合,不可能出现环。

    • 相互包含,此时考虑更新 \(pre\)\(suf\)

      • 区间 \(v\)\(u\) 的左儿子内:更新 \(suf_u\)\(suf_v\),然后递归,注意到实际上只需要把区间 \(u\) 变成它的左儿子就行了。

      • 区间 \(u\)\(v\) 的左儿子内:更新 \(pre_v\)\(pre_u\),然后递归,与上述同理。

      • 其他情况不需讨论。

    上述的递归指,暴力扫出所有与它有边的点进行 extend。

    启示:注意一些东西不需要实时维护的就不要实时维护,类似于搞一个懒标记会更好。

    时间复杂度:势能分析可得为 \(O((n+m)\log k)\),评价:Epic。Link

    22-06-25

    SNOI2017 炸弹

    极其显然的有一个线段树优化建图的大复杂算法,很明显我不想写,不过考场上可能就开冲了,时间复杂度 \(O(n\log n)\),期望得分 \(100\) 分,但是很难写,爪仑还在写!!!1。

    有一个更为优秀的一个单调栈做法,虽然实际上较为隐性:

    考虑先求出单独向左炸炸的最远是 \(L_i\),这里同时用向左的炸弹反向炸回可能炸出的半径 \(r_{L_i}-(x_i-x_{L_i})\) 更新 \(r_i\),这是一个类似单调栈的过程,线性完成:

    FOR(i,2,n) while(L[i]>1&&x[i]-x[L[i]-1]<=r[i]) {
        r[i]=max(r[i],r[L[i]-1]-(x[i]-x[L[i]-1]));
        L[i]=L[L[i]-1];
    }
    

    接下来考虑 \(R_i\) 的求出,注意这里可能存在右边炸左边的情况,同时左边炸右边已经在上面考虑:

    ROF(i,n-1,1) while(R[i]<n&&x[R[i]+1]-x[i]<=r[i]) {
        L[i]=min(L[i],L[R[i]+1]);
        R[i]=R[R[i]+1];
    }
    

    由此,问题在 \(O(n)\) 的时间复杂度内完成,评价:Great。

    启示:对于一道题目需要有所取舍。Link

    SNOI2020 水池

    纯纯的码农题,我还没写,先鸽一会。

    一个一个操作来分析:

    • 操作一:实际上是向左找出第一个高过 \(h\) 的挡板,向右找出第一个高过 \(h\) 的挡板,然后就 cover 一下完事。

    • 操作二:考虑向左找到与之液面相平的,向右找到与之液面相平的,此时左边液面变为右挡板高度,右边液面变为左挡板高度,打懒标记即可。

    • 操作三:单点修改,跑路。

    • 操作四:单点询问,跑路。

    可持久化就可持久化线段树就行了。

    时间复杂度 \(O(n\log n)\),评价:Trash。

    坑点:修改操作二的时候注意依赖顺序。

    启示:想清楚再搞。Link

    22-06-26

    CTT2017 简单数据结构

    数据结构测试考这个?

    这个题显然不是数据结构,直接 DP。

    因为题目涉及到开头数,所以设 \(f_i\) 表示以 \(i\) 开头的最长上升倍数倍数子序列长度,\(g_i\) 表示答案为 \(i\) 的开头个数。

    题目有以下三个特殊点:

    1. 每个数互不相同。

    2. 值域是 \(10^6\) 而非 \(10^9\)

    3. 每个数最多进来 \(10\) 次。

    根据 1.,\(f_i\) 的最大值仅为 \(20\),因为 \(2^{20}=1048576>10^6\),所以说在维护出来 \(f_i\) 之后我们可以以 \(\log M\) 的时间复杂度内求出答案,这部分的复杂度是 \(O(Q\log M)\)

    接下来的问题是维护 \(f_i\),考虑要求的操作:

    • 左边插入,枚举一手倍数,是均摊 \(\log\) 的。

    • 左边删除,最左边的一点影响都没有 haha,直接删了跑路。

    • 右边插入,我们需要枚举约数,考虑到一些更新上的问题,我们新设出 \(h_{i,j}\) 表示以 \(i\) 开头的,长度为 \(j\) 的上升倍数倍数子序列有多少个,这样可以以 \(\log M\) 的代价推出 \(f_i\)

    • 右边删除,与上面类似。

    发现单次复杂度很诡异,是 \(d(M)\log M\) 的,所以复杂度就是 \(O(Qd(M)\log M)\) 了?但是就是过了。

    评价:Great,Link

    启示:注意到每一个细节,一些看似不可做的题可以迎刃而解。

    APIO2022 交互库配置

    虽然好像不算做题,但是先写进来吧。

    配置了一手 APIO 的三个题,感觉上还在架构上存在一些问题,可能后期还需要调整?

    • mars:唯一的通信题,在配置的途中暂时没有考虑传信息的可能,我感觉打乱交互顺序就行了,暂时先搁着,等有人这样艹过去了再来改。

    • game:挺鬼畜的交互库解法,十分神必,大概是保证了次数一定用完?感觉有点拉,我在修改的时候把自己标程粘上去了。

    • perm:最简单的配置吧,All OK。

    加起来就用了 4h+ 吧,慢了。

    22-06-27

    BJOI2019 光线

    随机到的,什么沙比提。

    考虑合并两块玻璃,求出新玻璃的折射率与透光率。

    \[a=a_ia_j+a_ib_jb_ia_j+a_ib_jb_ib_jb_ia_j+\ldots=a_ia_j(1+b_ib_j+(b_ib_j)^2+\ldots)\\ b=b_i+a_ib_ja_i+a_ib_jb_ib_ja_i+\ldots = b_i+a_i^2b_j(1+b_ib_j+(b_ib_j)^2+\ldots) \]

    由等比数列求和,或者说 \(\frac 1 {1-x}\) 这类封闭形式,有:

    \[a=\frac{a_ia_j}{1-b_ib_j},b=b_i+\frac{a_i^2b_j}{1-b_ib_j} \]

    模拟即可,时间复杂度 \(O(n\log \bmod)\),作为送分题十分到位,评价:Common。

    Hint:以后还是自己写一个 modint 好,不然这种蠢题又会调上一会。Link

    网络流 - 区间选择模型

    Link

    22-06-28

    CF632E Thief in a shop

    纯纯的智障提,拿来复习 NTT 了。

    \(f(x)=\sum x^{a_i}\),那么选 \(k\) 次也就是 \(f^k(x)\),直接快速幂即可。

    也可以用多项式快速幂做到更优复杂度,我没写。Link

    坑点:注意 IDFT 的时候要翻转的值是全部,不要写挂了。评价:Common

    lgP7844 「dWoi R2」FFT

    看着好难啊,没什么性质!

    不如先打一手表,就以样例为例,打出 \(k=20\) 的表(只截取了 \(k=10\) 的):

    36 894301004 346334868 201631260 998244349 796613085 651909477 103943341 0
    8 64 56 48 40 32 24 16 0
    288 831546728 224054051 383438562 998244321 614805727 774190238 166697561 0
    64 128 192 256 320 384 448 512 0
    2304 335336135 204055786 925468404 998244097 72775437 794188055 662907706 0
    512 4096 3584 3072 2560 2048 1536 1024 0
    18432 312039883 364038322 582203496 998242305 416036761 634201935 686200374 0
    4096 8192 12288 16384 20480 24576 28672 32768 0
    147456 498381227 82393715 333561029 998227969 664650556 915817870 499830358 0
    32768 262144 229376 196608 163840 131072 98304 65536 0
    

    首先一次 DFT 的结果肯定没什么用,考虑一下数字比较小的结果,\(k=2\)\(k=4\) 的。

    \(k=2\) 似乎没有什么大文章,但是 \(k=4\) 就来劲了,\(128=64\times 2\)\(512=64\times 8\),就是说 \(k=4\) 的结果就是原序列乘上 \(64\) 的结果,\(64\) 是什么?

    \(64=2^6=(2^3)^2\),可以猜一手每 \(4\) 轮操作就是把原序列乘上了 \((2^n)^2\)

    然后写一发,然后就过了!Link


    证明(下文用 \(n\) 代替 \(2^n\)):

    DFT 的本质是乘上一个矩阵 \(V\)

    \[V= \begin{bmatrix} 1 & 1 & 1 & \cdots & 1\\ 1 & \omega^1 & \omega^{2} & \cdots & \omega^{n-1}\\ \vdots & \vdots & \vdots & \ddots & \vdots\\ 1 & \omega^{n-1} & \omega^{2(n-1)} & \ldots & \omega^{(n-1)(n-1)} \end{bmatrix} \]

    \(V\) 没什么性质,考察 \(V^2\)

    \[V^2_{i,j} = \sum_{k=0}^{n-1} \omega^{ik+kj} = (\sum^{n-1}_{k=0} \omega^{k})\omega^{i+j} \]

    除非 \(i+j=n\) 或者 \(i+j=0\),否则 \(\sum \omega^k\) 会变成 \(0\),所以说:

    \[V^2= \begin{bmatrix} n & 0 & 0 & \cdots & 0\\ 0 & 0 & 0 & \cdots & n\\ \vdots & \vdots & \vdots & \ddots & \vdots\\ 0 & 0 & n & \cdots & 0\\ 0 & n & 0 & \cdots & 0 \end{bmatrix} \]

    这等价于总体乘上 \(n\) 后将 \(1\sim n-1\) 项翻转过来。

    所以做四次的时候结论就出来了。


    评价:Great。

    感觉做这种题首先是可以打表的,同时注意单次操作如果没性质要考虑多次操作。

    HNOI/AHOI 2017 礼物

    设加上了 \(c\),那么答案就是:

    \[\sum (a_i-b_i+c)^2\\ \sum a_i^2+b_i^2+c^2-2a_ib_i+2a_ic-2b_ic\\ \sum a_i^2+\sum b_i^2 + nc^2-2\sum a_ib_i+2c\sum a_i-b_i \]

    除了 \(\sum a_ib_i\),其他都可以暴力枚举。

    假设转了 \(k\) 位,那么就是求 \(\sum a_{i+k}b_i\) 的最大值,这是一个差卷积,将 \(b\) 倒序,\(a\) 倍长,跑 NTT 即可。

    时间复杂度 \(O(n\log n)\),评价:Great。

    坑点:注意乘起来的是 Poly 数列不是原数列。Link

    lg4173 残缺的字符串

    这里要提到的是 FFT 加速字符串匹配。下文是一般的解法:

    考虑构造一个函数 \(f(x,y)\) 表示 \(A_x\)\(B_y\) 是否相等,设 \(g(x)\) 表示来判定 \(A\)\(B[x,x+m-1]\) 完全匹配,为 \(0\) 则匹配,则 \(g(x)=\sum_{i=1}^{m} f(i,i+x-1)\)

    这里注意 \(f(x,y)=A_x-B_y\) 不可行,理由是正负可以抵消。

    构造 \(f(x,y)=(A_x-B_y)^2\),那么 \(g(x)=\sum^m_{i=1}(A_i-B_{i+x-1})^2\),套路地拆开括号,有 \(g(x)=\sum^m_{i=1}A_i^2+B_{i+x-1}^2-2A_iB_{i+x-1}\),前面搜义贼,后面是差卷积,可以在 \(O(n\log n)\) 的时间复杂度内解决。

    回到原问题,我们只需要处理通配符,构造 \(f(x,y)=A_xB_y(A_x-B_y)^2\),这个意思是通配符对应 \(0\)。同样的拆开括号:\(g(x)=\sum_{i=1}^m A_i^3B_{i+x-1}-2A_i^2B_{i+x-1}^2+A_iB_{i+x-1}^3\),还是差卷积,\(O(n\log n)\) 卷一手跑路。

    22-06-29

    AGC006

    Link

    22-06-30

    lg5641 开拓者的卓识

    卡题,好啊。

    考虑算贡献,对于一个 \(a_i\),考虑他对区间 \([1,r]\) 的贡献。这等价于有一个 \([i,i]\subseteq[l_1,r_1]\subseteq\ldots\subseteq[l_k,r_k]\subseteq[1,r]\)

    注意到这等价于 \(1\le l_k\le \ldots\le l_1\le i\le r_1\le \ldots\le r\),可以使用插板法算出贡献,那么 \(\displaystyle f(k,1,r)=\sum^r_{i=1}a_i\times \binom{i+k-2}{k-1}\times \binom{r-i+k-1}{k-1}\),裸的卷积。

    使用 NTT 优化卷积,同时递推组合数,可以做到 \(O(n\log n)\)

    JSOI2012 分零食

    感觉没那么难?考虑 \(f_{i,j}\) 表示 \(i\) 个人分 \(j\) 个糖果没有人没得的乘积总和,有:

    \[f_{i,j}=\sum_{k=1}^j f_{i-1,j-k}g(k) \]

    这是一个卷积,将 \(g(k)\),也就是原题中的二次函数,以及 \(f(i,j)\),写成生成函数形式:

    \[F_i(x)=F_{i-1}(x)G(x) \]

    所以 \(F_i=G^i\),问题变成求 \(\sum_{i=1}^{A} G^i\),这是一个等比数列求和,容易推出答案是:

    \(\frac {1-G^{A+1}}{1-G}\),直接计算即可。

    注意到模数很小,所以实际上可以在 NTT 内部使用 NTT 模数,而在外部使用其他模数,同时求的项是固定的,可以利用这个来剪枝。

    lg5488 差分与前缀和

    前缀和等同于乘上 \(G(x)=\sum_{i=0}^{+\infin} x^i\),根据等比数列求和就是 \(G(x)=\frac{1}{1-x}\)

    \(k\) 维就乘 \(k\) 次,差分就逆过来,解决问题。

    22-07-01

    重新用 vector 实现了多项式 inv,ln,exp,不想搞了,休息一下。

    ZJOI2016 随机树生成器

    哈哈,不会随机分析,直接乱试。

    你就随便生成 \(2\times 10^5\) 棵树然后选一个值试一试就行了,我乱搞出来的方法:

    • \(deg^2>5550\),第一种方法。

    • 用每个点每棵子树的 siz log 和区分出第四种方法。

    • 用每个点到最远一度点距离之和区分第二第三种方法。

    然后 \(O(n)\) 做一下,选取合适的阈值即可。

    (22-07-03 才做完的/kk)

    22-07-03

    做完了 ZJOI2016 随机树生成器,胡了一手 PR,然后就没了。

    22-07-04

    ARC142F Paired Wizards

    Surrendered。

    注意到造成的伤害是可以量化的,具体的,如果有人在 t 时刻使用了第 i 次操作 2,实际上的贡献是 \(t-i\),这个贡献可以拆开计算,设 \(\sum t\)\(s_x,s_y\),次数是 \(c_x,c_y\),则答案是 \(s_x+s_y-\frac{c_x(c_x+1)}{2}-\frac{c_y(c_y+1)}{2}\)

    针对这个进行讨论:

    • 两边相同的情况。即无论如何都要用这个操作,直接无脑累加上去。

    • 一个人的操作已经固定,另一个人并不固定,也就是说此时 \(a=c\) 或者 \(b=d\)。这种情况先累加上固定的人的贡献,然后考虑另一个人选一还是选二,有一种贪心的直觉是选二一定是个后缀,事实上可以用调整证明,这里不证了。

    • \(1122\) 型,也就是说此时要么全部选一,要么全部选二。同样的选二一定是个后缀。

    • \(1221\) 型,注意到此时两个人必有一个人贡献,可以考虑枚举有多少次谁贡献。

    针对第二种类型,我们考虑预处理 \(f_i\) 表示第一个人做 \(i\) 次操作二之后的最大代价,g_i 同上,那么我们就可以先枚举第四种类型中多少次谁贡献,然后枚举第三种类型中的后缀,时间复杂度 \(O(n^2)\)

    为了实现方便,我们可以考虑将 \(f_i\)\(g_i\) 中一些固定的部分延后统计。

    ICPC 2021 Yokohama H Cancer DNA

    哈哈,想到的做法被点名批评。

    赛时的想法是:考虑容斥,容斥是可以算出精确值的,但是复杂度是 \(O(2^m)\) 的,考虑剪枝。

    想到选的点越多,有方案的概率越低,选少一些点跑的贡献要大很多,再加上 \(m\) 很小,是不是就可以过了?但是有方案的概率越低,这种概率较低的情况很多很多,就寄了。

    所以考虑抽样,抽一个 \(t\) 出来,计算概率,但是你的 \(t\) 大概率是不合法的,所以我们从合法的抽一个出来。

    怎么找合法的呢,我们希望找到一个限制最小的 \(s_i\),但又不能每次找到它,从这个 \(s_i\) 为蓝本随机一个串 \(t\),找出与之匹配的全部串,设这有 \(x\) 个,为它们加上 \(\frac{1}{x}\) 的权值,最后统计即可。

    BZOJ3732 Network

    沙比提,建出最小生成树,答案是最小生成树上 \((u,v)\) 间的最大值,时间复杂度 \(O(m\log m+q\log n)\)

    ONTAK2010 Peaks

    强制在线做法。

    考虑到 Kruskal 重构树的性质,\(\le x\) 的路径显然就是往上跳可以调到的权值至多为 \(x\),第 \(k\) 大吗,DFS 序+主席树即可了。

    时间复杂度 \(O(m\log m+q\log n)\)

    22-07-05

    学习了矩阵树定理,但不会证明,内容如下:

    定义拉普拉斯矩阵为度数矩阵减去邻接矩阵的结果,我们不加证明地写出如下结论:

    拉普拉斯矩阵去除任意一行的新矩阵的行列式值就是该无向图生成树个数。

    针对有向图的情况,只需要根据叶向树/根向树将度数矩阵修改为入度/出度矩阵即可。

    行列式建议使用辗转相除消元的方法。

    板子题都写了(HEOI2015 小 Z 的房间、BZOJ4894 天赋、CQOI2018 社交网络、JSOI2008 最小生成树计数)。

    其中最小生成树计数有特殊做法,就是先跑一棵,然后针对每一种边权计算生成树个数。

    JSOI2009 计数问题:沙比提,二维树状数组搞一搞就行了。

    22-07-06

    lg4898 Preprefix sum:\(SS_i=\sum_{j=1}^i\sum_{k=1}^j a_k=\sum_{j=1}^i a_j(i-j+1)=(i+1)\sum_{j=1}^ia_j-\sum_{j=1}^i a_jj\),分开维护即可。

    lg4514 上帝造题的七分钟:考虑一维的情况怎么做,是不是差分然后化式子,那么二维也这么做。具体的,我们差分修改,针对询问实际上就是求 \(\sum\sum a_{i,j}\times (x-i+1)\times (y-j+1)\),暴力拆开分别维护 \(a_{i,j},ia_{i,j},ja_{i,j},ija_{i,j}\) 即可。

    lg4915 帕秋莉的魔导书:答案和 lg4898 是一样的形式,注意到这里值域很大,使用动态开点树状数组即可。

    CF896C Willem, Chtholly and Seniorious [*2600]

    大部分人的 ODT 入门题,考虑使用 set 维护值域连续段。

    每次 cover 我们可以快速做到,所以这其实就是个暴力,其他操作暴力做就行了。

    22-07-07

    SDOI2017 相关分析

    针对修改操作,考虑维护的东西。

    首先 \(\overline{x}\)\(\overline{y}\) 可以直接维护 \(\sum x\)\(\sum y\) 解决,将这两个看成常量,那么 \(a=\frac{\sum_{i=L}^R (x_iy_i-\overline{x}y_i-\overline y x_i-\overline x\overline y)}{\sum_{i=L}^R(x_i^2-2\overline x x_i+\overline x^2)}\)。 再维护 \(\sum xy\)\(\sum x^2\) 即可。

    区间加 so easy,区间修改转成覆盖等差数列加区间加即可。

    HNOI2009 梦幻布丁

    不写平衡树!!!!写启发式合并就行了。

    具体的,用一个容器存储一手每一种颜色存在的所有值,接下来考虑将小的合并到大的上即可。

    AHOI2006 文本编辑器

    不写平衡树!!!rope 板子题!!!

    用两个 rope 维护前后的字符串即可。

    SPOJ TTM

    用可持久化线段树进行维护即可,注意时间的标记。

    TJOI2014 电源插排

    用动态开点线段树维护最长的全 \(0\) 段,其对应的中心即可。

    维护方式和 GSS3 类似。

  • 相关阅读:
    window.clearInterval与window.setInterval的用法(
    hibernate 使用in方式删除数据
    hibernate中一对多Set的排序问题
    struts2 标签的使用之一 s:if(遍历中s:if如何用等)
    hibernate使用sql语句查询实体时,要写上addEntity
    struts通过Ajax返回数据时,例如对象类型,没有执行Ajax的回调函数
    hibernate 对象状态异常:object references an unsaved transient instance
    ${}与 $()区别
    hibernate逆向工程生成的实体映射需要修改
    本地tomcat的start.bat启动时访问不出现小猫图标
  • 原文地址:https://www.cnblogs.com/cnyzz/p/16409787.html
Copyright © 2020-2023  润新知