【刷题笔记】AT 经典 90 题
T2
爆搜
注意,string 只能与 string 运算,无法和 char 运算;访问 string 某一位时则是 char
T5
数位 DP。
转化题意:若 \(x\) 是 \(B\) 的倍数,则 \(x\mod B = 0\)。
先设计 DP 状态,设 \(f_{i,j}\) 表示看到第 \(i\) 位,且前 \(i\) 位组成的数模 \(B\) 为 \(j\)。
则 DP 转移方程:
\(f_{i + 1, (j + k \times 10 ^ i)\mod B } = f_{i + 1, j + (k \times 10 ^ i)\mod B } + f_{i,j}\)
由于当前这一位是任意的,没有任意限制,所以这玩意可以用矩阵快速幂转移,但是时间复杂度上还不够优。
发现转移矩阵中 \(1\) 的个数很少,所以舍弃矩阵改用倍增。改变 DP 状态为 \(f_{i,j}\) 表示看到第 \(2^i\) 位,且前 \(2^i\) 位组成的数模 \(B\) 为 \(j\)。转移方程:
\(f_{i + 1, (j + k \times 10 ^ {2^i})\mod B } = f_{i, j} \times f_{i,k}\)
T12
注意:在并查集合并时,如果某个点的父亲在不停改变,那么在合并时,一定是将最新的父亲合并。
T16
调和级数 + 数学
敲黑板:
1.做类似题时,可以先将必选所限制的去掉
2.将 \(n\) 个数分成 \(m\) 组,每组 \(\ge 0\),则有 \(C_{n + m - 1} ^ {m - 1}\)
T23
轮廓线 DP。
注意!! 总状态数很多很多 \(O(2^{24})\),所以要先搜出基本合法的状态(不存在两个相邻的 \(1\))(当然这样的状态也可能是不合法,但是这已经能大大减少总方案了,好像总方案大约为 \(O(10^5)\) 左右)。
还有就是注意只有 \(1\) 列的情况。
T25
超级无敌的神仙题。
考虑暴力枚举 \(m\) 的长度然后暴力枚举每一位的数值 \(1\sim 9\),最后别忘特判数中存在数字 \(0\) 的情况(此时 \(f(m)=0,m = B\))
但是发现枚举 \(f(m)\) 再看是否存在对应的 \(m\),比枚举 \(m\) 再看是否存在对应的 \(f(m)\) 要优。
为了不重不漏,可以枚举一个不降序列,作为 \(m\) 的各位,将序列中的各个数字乘起来当作 \(f(m)\),发现在 \([1,10^{11}]\) 中符合要求的 \(f(m)\) 好像只有 \(70000\) 多,即在 \([1,10^{11}]\) 中能被分解为 \(1\sim 9\) 相乘的数是极少的。
特别注意,枚举 \(f(m)\),算出 \(m\) 后别忘判 \(m\le n\)
T30
在用欧拉筛筛质数的时候,同时计算每个数可以被分解为多少不同的质因数。
cnt[i * prime[j]] = cnt[i] + (i % prime[j] > 0);
T31
SG 函数,被秒了。
T59
无向图 的连通性可以用并查集维护,那么 有向图 呢?
敲黑板!!!! 可以用 bitset 维护。
对于每个点可一个 bitset,用 \(bs_{u,v}\) 记录 \(u\) 是否能到达 \(v\),然后建反图跑一边拓扑排序,每次 若原图上 \(u\) 能到 \(v\) 则 \(bs_u |= bs_v\)。时间复杂度 \(O(m\times \frac{n}{w})\)
但是这就完了吗,不,空间会炸。
于是折半大法,先处理 \(\le md\) 的询问,再处理 \(> md\) 的询问,这样就可以将空间减小一半。
T62
又又是一道神仙题。
形式化题意:将 \(A_i,B_i\) 分别向 \(i\) 连边。则题目变成了删点,只能删入度 \(\ge 1\) 的点,给出一种将题目中的所有点删完的方案。
经典转化 删点变加点:倒着加点,若新加入 \(u\),则将 \(u\) 相连的所有点入度 \(+1\),若有新的点入度变成 \(1\),那么就加入他,然后再用他去扩展更多点。写个类似拓扑排序的东西就过了。
T71
边深搜边拓扑。
用一个 deque 记录当前可选的点有哪些,每次选一个就点把他 pop_front(),然后把能直接到达的点入度减一,用完后 push_back()(保证每个点只会被选一次)。
一个点能被加入 deque 当且仅当他的入度为 \(0\) 时。
无解的情况可能有两种:
- 拓扑图有环
- 限制太严了,凑不出 \(k\) 种方案。
一点要先判第一种情况,不然可能会一直搜直到搜满所有情况,就炸了。
时间复杂度 \(O(kn)\),因为每次搜(要是没环)必然能搜出一种方案,搜出一种方案时间复杂度 \(O(n)\)。
T80
暴力容斥(钦定哪些条件不被满足)/状压 DP。
注意:
- \(2^{20}>10^6+10\)
__builtin_popcount的参数是int类型,要是参数是long long要写__builtin_popcountll1 << 40会爆int要写1ll << 40
T83
又又又是一道神仙题。
若边数共 \(m\) 条,则每个点的度数和为 \(2m\),所以度数大于 \(\sqrt m\) 的点最多 \(O(\sqrt m)\) 个。
设 \(tag_x\) 表示 \(x\) 的标记,\(ans_x\) 表示最晚更改 \(x\) 的询问编号。
考虑根号分治。对于每次染色,若 \(x_i\) 的度数大于 $\sqrt m $ 就在点上打一个标记 \(i\),否则就暴力染色,更改每个点的 \(ans\)(初始为 \(0\))。
对于每次查询,将 \(x_i\) 的 \(ans\) 与于他相连的所有度数大于 \(\sqrt m\) 的点的 \(tag\) 取 \(\max\) 记为 \(w\),答案就是 \(y_w\)。

浙公网安备 33010602011771号