Loading

THUSC 补题

P4681 [THUSC2015] 平方运算

假如对一个数 \(x\) 进行 \(k\) 次平方运算,那么得到的数是 \(x^{2^k} \bmod p\)。根据扩展欧拉定理,这个数是

\[\begin{cases} x^{2^k}\bmod p & 2^k<\varphi(p)\\ x^{2^k \bmod \varphi(p)+\varphi(p)}\bmod p & 2^k>\varphi(p) \end{cases}. \]

打表可以发现 \(2^k\bmod \varphi(p)\) 的值呈 \(\rho\) 形排列,且循环节外的部分、循环节长度都很短。所以先算出循环节开始的位置 \(l\) 和循环节长度 \(c\)。对于那些操作次数 \(<l\) 的数,在线段树上暴力平方;对于那些操作次数 \(\ge l\) 的数,预处理出循环节内的每个值,然后就可以支持懒标记了。修改时用 std::rotate 即可。

时间复杂度 \(\mathcal{O}((l+c)m\log n)\)代码

几个写错的地方:

  1. 要注意 std::rotate 的参数顺序,并且要注意取模。
  2. 线段树查询时也要 pushdown!!!

P5335 [THUSC2016] 补退选

我的做法太阴间了。这里写一个正常的做法。

建出 Trie 树,在每个节点上用 fat node 的方法记录前缀最大出现次数。查询时找到对应的节点并在 vector 内二分。

P5794 [THUSC2015] 解密运算

只想到了 \(\mathcal{O}(n^2)\) 做法。

设输入的数组是 \(a_{1\dots (n+1)}\)

先考虑没有重复数字的:如果将 \(a\) 从小到大排序得到 \(b\),那么 \(\forall i\)\(a_i\) 一定在 \(b_i\) 的前面一个位置。因为没有重复数字,所以顺序就能确定了。

如果有重复数字,那我们需要辨别出 \(a\) 中的某个 \(x\) 对应的是 \(b\) 中的哪个 \(x\)。对于字符串 \(S\),设 \(\operatorname{rsh}(S)\) 为将 \(S\) 循环右移一位得到的字符串。考虑题目中的那个矩阵,它是按照字符串的字典序排序的,设这 \((n+1)\) 个字符串的编号为 \(1,2,\dots,(n+1)\),第 \(i\) 个字符串设为 \(S_i\)。假如按照 \(\operatorname{rsh}(*)\) 的字典序排序,并设 \(c_i\) 为排序后第 \(i\) 个字符串原先的编号、\(S'_i\) 为排序后第 \(i\) 个字符串,因为将所有字符串都 \(\operatorname{rsh}\) 一次再排序,得到的结果和原来是相同的,所以 \(\forall i,S_i=S'_i\)。所以 \(S_{c_i}\) 的末位字符,就是答案中 \(S_i\) 的末位字符的后一个字符。

但还有一个问题:我们不知道原先的完整矩阵,如何进行排序?考虑以 \(a_i\) 为第一关键字、\(i\) 为第二关键字排序,可以发现这样的排序方式能保证字典序。

P5336 [THUSC2016] 成绩单

我为啥没想到啊。

首先离散化。

考虑暴力:设 \(f_{i,j,S}\) 为将 \(w_{i\dots j}\) 中所有不在 \(S\) 内的元素都消除,所需的最小代价。对于 \(S\) 为空的情况,令 \(\operatorname{cost}(S)=a+b(\max\{S\}-\min\{S\})^2\),有转移:

\[f_{i,j,\varnothing}=\min_{S} \{f_{i,j,S}+\operatorname{cost}(S)\}\\ \]

对于 \(S\) 不为空的情况,设 \(T_k=\{x\mid x\le k\land x\in S\},W_k=S-T_k\),有转移:

\[f_{i,j,S}=\min_{i\le k<j}\{f_{i,k,T_k}+f_{k+1,j,W_k}\} \]

可以发现只需要记录集合的最大值和最小值就能转移。所以设 \(f_{i,j,l,r}\) 表示保留 \(w_{i\dots j}\) 中值在 \([l,r]\) 间的元素,而消除其他所有元素,所需的最小代价,而 \(g_{i,j}\) 表示消除 \(w_{i\dots j}\) 中所有元素的所需代价。于是就可以转移了,注意这样会加上 \(g+f\to f\)\(f+g\to f\)\(g+g\to f\) 的转移。

P7453 [THUSCH2017] 大魔法师

用线段树维护行向量,修改时右乘一个矩阵即可。对于 \(A_i=A_i+v\)\(C_i=v\) 的操作,需要多在矩阵里记录一个常数。

众所周知矩阵乘法是 \(C_{i,j}=\sum_{k} A_{i,k}\times B_{k,j}\),如果按照 \(k,i,j\) 的顺序进行循环,速度会快一些。

posted @ 2022-05-21 20:33  Alan_Zhao_2007  阅读(73)  评论(0编辑  收藏  举报