算法中的一些巧妙用法及总结
算法技巧
字符串哈希
当我们预处理出一个字符串的哈希值后,可以\(O(1)\)的求出删除中间任意一个字符后的字符串的哈希值。
设长度位\(len\),哈希表进制为\(base\),删除第\(k\)位
则
\[HASH=hs[k-1]*base^{len-k}+hs[len]-hs[k]*base^{len-k}
\]
质数与因数相关
求一个数的因子数
对于一个有\(m\)个质因子的数\(x\),有
\[x=a_1^{k_1}*a_2^{k_2}*\cdots*a_m^{k_m}
\]
设\(x\)的因子数为\(f(x)\),则
\[f(x)=(k_1+1)*(k_2+1)*(k_3+1)*\cdots*(k_m+1)
\]
由此可进而推得,若想要去掉一个数的一个任意因子,使得剩余的因子数最多,则应去掉所有质因子中指数最大的一个。
证明:显然,去掉质因子一定比去掉合数因子所剩的因子数最多。考虑指数与贡献的关系。观察上面式子可知,去掉任意一个质因子\(a_i\),即使得 \(a_i^{k_i}\)中的\(k_i\)变为\(k_i-1\),那么得到的数\(x'\)的因子数
\[f(x')=f(x)*\frac{k_i}{k_i+1}
\]
容易看出来,\(k_i\)越大,结果越大。因此要使得得到的新数因子数最多,以去掉一个指数最大的质因子,证毕。
迷宫问题
对于一些仅有两个不相反行进方向的走迷宫题目,可以考虑枚举步数和某一坐标,此时当一个坐标确定时,另一个坐标也可以确定。
如下
f1(i,3,n+m){
c='z';
f1(j,1,min(i,n)){
x=j,y=i-j;
if((f[x-1][y]||f[x][y-1])&&i-j<=m)c=min(c,s[x][y]);
}
putchar(c);
f1(j,1,min(i,n))if(s[j][i-j]==c&&i-j<=m&&(f[j-1][i-j]||f[j][i-j-1]))f[j][i-j]=1;
}
简单环的求解
考虑在欧拉回路中求简单环。
当我们使用dfs求出欧拉回路的路径且将其压入栈后,可以直接遍历欧拉回路,并依次将路径压入栈。
在这期间,一旦有一个点被偶数次经过,就可以弹栈,直到栈顶为该点时,停止弹出。
这些弹出的路径就会形成一个简单环。
可以保证所有的环互不重叠,但不唯一
例题
有关位运算
位运算有些结论是需要记忆的,随时可能会考
1.当一串数求与(\(&\))和时,要注意最大值一定会小于等于数列中的最小值
2.当选取一串数求或(\(|\))和时,每一次或运算一定不会让结果变小。
3.异或运算又称不进位加法,因此在异或运算下,他的每一位的计算可以看作独立的。又因为期望的可加性,所以异或可以结合期望算期望异或和。
4.任何一个数异或两次之后都等于0。