算法竞赛进阶指南-Part-one
0x03 基本算法-递归
HNOI2003]激光炸弹
做出二维前缀和,暴力枚举前缀和
给定一个长度为$ (n <= 10^5 ) \(的数列\){a_1,a_2,…,a_n}$,每次可以选择一个区间 [l,r],使下标在这个区间内的数都加一或者都减一。
求至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列可能有多少种。
考虑区间+1,-1无非是差分序列一个+1,一个-1,
最少操作次数:差分序列的绝对值最大项,
几种可能:差分序列的首项
Tallest Cow
题意:\(n\)头牛,两头牛可以互相看见当两头牛的之间的牛身高都小于,给出最高的牛的身高,和m对可以互相看到的牛,问每头牛的最高身高。
令\(c_i\)表示 \(i\) 头牛的身高,那么每当出现一对关系,就让 $ [l,r] $ 区间内的\(c_i -1\) ,暴力更新是不行的。做出 \(c_i\) 的差分序列 \(d_i\) ,每次更新时让 \(d_{l+1}-1\),\(d_{r}+1\) ,那么实际上求差分序列的前缀和即可。
\([差分序列的前缀和就是原序列,前缀和的差分序列也是原序列]\)
0x04 基本算法-二分
Best Cow Fences
题意;给定一个序列,求平均数最大的,长度不小于 \(l\) 的连续子段
二分这个平均数,每次判断是否存在一个长度 \(> = l\) 的连续子段。单调性显然。
判断的技巧在于:把 \(a_i\) 减去这个平均数,求一个长度 $ > = l$ 最大连续字段和,若最大连续字段和 $ > = 0$ , 则成立。
0x05 基本算法-排序
货仓选址
序列中选一个数,使得这个点到其他点的距离和最小,
必然是中位数最小,因为左边有 \(p\) 个,右边有 $ q$ 个,每次往右移动答案变大 \(p-q\),当 \(p=q\) 时答案最优。
0x14 基本数据结构-Hash
Snowflake Snow Snowflakes
求是否存在两个旋转之后一样的序列,
令\(H(x)=(\Sigma_{i=1}^{6}{a_i}+\Pi_{i=1}^{6}a_i)\%P\)
这样哈希实际上保证同一个排列的hash值一样,把同一个排列的雪花插入一个表里,暴力搜索这个表,
考虑平均分配的情况下,复杂度为\(O(n^2/p)\), 取 \(p\) 为最接近\(n\)的质数,期望复杂度约为$O(n ) $ 。
兔子与兔子
给出一个字符串,每次询问两个区间的字符串是否完全一样。
暴力复杂度为 \(O(n^2)\) ,把字符串哈希为p进制后,复杂度 \(O(n log(n))\),取p=131, 把一个字符串看成p进制后哈希,实际上判断两个字符串是否相等,就是判断两个哈希后的p进制的数是否相等。
0x16 基本数据结构-Trie
题意:给出n个字符串,m次询问给出字符串t,问n个字符串里有多少个是t的前缀,
字典树直接查询。
字典树遇到 \([trie[p][n]==0]\) 应该直接break掉
给出一个序列,问两个数异或结果最大应该是多少,
每个数插入01字典树里,直接反着查询即可。
建立字典树 \(O(nlog(n))\) , 查询 \(Onlog(n)\)
题意:问树上两点路径权重异或最大。
令 \(d_i\) 表示从根节点到 \(i\) 的异或值,那么任意两点 \(u,v\) 的异或值就是 \({d_u}\)^\({d_v}\) ,因为如果在一条路径上,相同的路径可以直接异或掉,剩下的就是没有异或的。
先dfs求 \(d_i\),然后字典树直接查询。
0x21 搜索-树与图的遍历
题意:给定一张N个点M条边的有向无环图,分别统计从每个点出发能够到达的点的数量。\(N,M≤30000。\)
直接暴力拓扑 \(O(n^2)\) , 用bitset维护每一个点能够到达的点,那么拓扑之后反着计算,儿子能够搞到的,父亲也能搞到,ans[u]|=ans[v]
0x31 数学知识-质数
题意:给出 \(l,r\), 询问 \([l,r]\) 区间内相邻的质数差最大、最小是多少。\(l,r<=2e9,r-l<=1e6\)
不能暴力筛出 \([1,r]\)以内的质数,但是可以预处理筛出\([1,\sqrt{r} ]\)内的质数,
先筛出\([1,50000 ]\)内的质数,每次获得\(l,r\)后,筛掉\([l,r]\)区间里的合数,复杂度\(O(\sqrt{n}*log(\sqrt{n}))\).
题意:给定整数 \(N(1≤N≤1e6)\),试把阶乘 $N! $分解质因数,按照算术基本定理的形式输出分解结果中的 $pi $和 \(ci\) 即可。
暴力扫描,然后合并的复杂度为\(O(n\sqrt{n})\).
考虑一个质数\(p_i\)的个数在\([1,n]\) 分别为\(cnt[p],2*cnt[p^2],3*cnt[p^3]....\)
\(n!\)中\(p_i\)的个数为:\(\lfloor \frac{n}{p} \rfloor+\lfloor \frac{n}{p^2} \rfloor+\lfloor \frac{n}{p^3} \rfloor+.....\)
先欧拉筛出\([1,n]\)中的质数,再分解。复杂度\(O(nlog(n))\) .
题意:对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。如果某个正整数x满足:$g(x) > g(i), 0 < i < x $ ,则称x为反质数。
例如,整数1,2,4,6等都是反质数。现在给定一个数N,你能求出不超过N的最大的反质数么?
N<=2e9.
先要求出[1,n]之间的反质数,把每一个数进行唯一分解:\(x=2^{c1}*3^{c2}*5^{c3}....\)
因为\(\Pi_{i=2}^{31}>2e9\),所以反质数一定可以由{2,3,5,7,11,13,17,19,23,29}分解而来.
而且反质数的幂数一定是递减出现的,这样贪心的保证相同约数的情况下数最小,
暴力枚举幂数的递减排列,搜出所有的反质数,然后按约数取最大。
给定n,k<=1e9,求\(\Sigma_{i=1}^{n}k\%i\)
\(\Sigma_{i=1}^{n}k\%i=n*k-\Sigma_{i=1}^n{\lfloor\frac{k}{i}\rfloor}*i\)
对于\(\lfloor\frac{k}{i}\rfloor\),显然具有分块的性质.
对于区间\([l,r]\),若他们的\(\lfloor\frac{k}{i}\rfloor\)相等,那么\(\lfloor\frac{k}{l}\rfloor= \lfloor\frac{k}{r}\rfloor\)
令\(t=\lfloor\frac{k}{l}\rfloor\),那么区间内的数满足\(\lfloor\frac{k}{i}\rfloor=t\),即\(i*t<=k\),即\(i<=\lfloor\frac{k}{t}\rfloor\),所以\(r=\lfloor\frac{k}{t}\rfloor\).
那么每个区间都是一个等差数列.
复杂度\(O\sqrt{n}\).