一些零散的知识

一些小技巧

求一个数的欧拉函数值,即求出 φ(n)

\(p_1,p_2,p_3,...,p_r\)\(n\) 的全部 \(r\) 个质因数,则有:

\[\varphi(n)=n\times(1-\frac{1}{p_1})\times(1-\frac{1}{p_2})\times(1-\frac{1}{p_3})\times(1-\frac{1}{p_4})\times…\times(1-\frac{1}{p_r}) \]

代码如下:

ans = n;
for (int i = 2; i * i <= n; i+=1)
{
    if (n % i == 0)
    {
        ans = ans / i * (i - 1);
        while (n % i == 0) n /= i;
    }
}
if (n > 1) ans = ans / n * (n - 1);
printf("%lld\n", ans);

ST 表

例题

求区间最大值。

ST 表能做到 \(O(n \log n)\) 预处理, \(O(1)\) 查询。

代码:

n = gi(), m = gi();
llog[1] = 0;
for (int i = 2; i <= n; i+=1) llog[i] = llog[i >> 1] + 1;
for (int i = 1; i <= n; i+=1) a[i] = gi();
for (int i = 1; i <= n; i+=1) f[0][i] = a[i];
for (int i = 1; i < 17; i+=1)
{
    for (int j = 1; j + (1 << i) - 1 <= n; j+=1)
    {
        f[i][j] = max(f[i - 1][j], f[i - 1][j + (1 << (i - 1))]);
    }
}
while (m--)
{
    int l = gi(), r = gi();
    int s = llog[r - l + 1];
    printf("%d\n", max(f[s][l], f[s][r - (1 << s) + 1]));
}

概率与期望

求期望时务必注意 逆推 !!!

有关 DP 的优化

从某种意义上来说,DP 的优化其实就是 对朴素代码进行等价变形,在变形的过程中减小时间复杂度。

主要有以下几种优化:

  • 单调队列优化;
  • 倍增优化;
  • 数据结构优化,其中包括线段树优化、树状数组优化等;
  • ……

排序不等式

有以下两个数列 \(\{g_i\}\)\(\{a_i\}\) ,保证 \(0 \leq g_1 \leq g_2 \leq ... \leq g_n\)\(0 \leq a_1 \leq a_2 \leq ... \leq a_n\)

那么要求出这两个数列两两配对相乘的乘积之和的最大值和最小值,就有:

  • 最大值为 \(g_1 \times a_1 + g_2 \times a_2 + ... + g_n \times a_n\)
  • 最小值为 \(g_1 \times a_n + g_2 \times a_{n - 1} + ... + g_n \times a_1\)

背包问题常见套路

一般的背包问题转移都是按照以下的顺序转移的:

状压 DP 常见套路

具体可以参考一下我 AcWing1064. 骑士代码AcWing327. 玉米田代码

常用技巧:

  • 可以使用 if (i >> j & 1) 来快速判断集合 \(i\) 中第 \(j\) 位是不是 \(1\),也常用于枚举子集;
  • 在转移时可以将第一维多转移一个数,答案直接输出多转移的那一维状态为 \(0\) 的答案即可,具体需参考代码;
  • 如果需要开滚动数组优化空间,并且只有两个状态之间相互转移的题目,可以直接在转移的一维 & 1 即可。

一种快速求组合数的方法

link

单调队列优化 DP

  • 优化 DP 时头尾指针要初始化成 hh = tt = 0
  • 一定要记住:判断队尾条件时条件的下标是 tt,不是 hh!!!所有单调队列的题都要注意!!!

常用建图方式

  • 建一个虚拟源点、虚拟汇点;
  • 直接按照题意建图;
  • 根据题目中的递进关系建图。

一些常用的思想

  • 前缀和思想;
  • 预处理的思想;
  • 差分思想;
  • 建图的思想;
  • DP——从集合角度分析的思想;
  • ……

求出 n! 的约数个数

AcWing197. 阶乘分解

代码

枚举一个数的所有约数

首先对这个数分解质因数,然后一遍 DFS 找出这个数的所有约数。

代码

斜率优化注意事项

  • 判断出队的条件是 hh < tt没有等于号!!!
  • 维护下凸包时:判断队头出队时是 \(\leq\),判断队尾出队时是 \(\geq\);维护上凸包时就反过来。
  • ……

前 n 个数和为 m 的方案数

可以考虑 DP。设 \(dp_{i,j}\) 表示前 \(i\) 个数和为 \(j\) 的方案数。

转移:\(dp_{i,j} = \sum\limits_{k=0}^{j-1}dp_{i-1,k}\)

然后发现其实就是 \(dp_{i,j}=dp_{i-1,j}+dp_{i,j-1}\),转化为格路问题就知道答案为 \(\binom{n+m-1}{m}\)

或者直接使用隔板法,答案也是 \(\binom{n+m-1}{n-1}=\binom{n+m-1}{m}\)

About 树上差分

  • 树上差分最终统计是在 回溯时 计算!!!

曼哈顿距离与切比雪夫距离的互换

将每一个点 \((x,y)\) 转化为 \((x+y,x−y)\),新坐标系下的 切比雪夫距离 即为原坐标系下的 曼哈顿距离

将每一个点 \((x,y)\) 转化为 \(\left(\frac{x + y}{2},\frac{x - y}{2}\right)\),新坐标系下的 曼哈顿距离 即为原坐标系下的 切比雪夫距离

About 冒泡排序

\(c_i\) 为第 \(i\) 个数有多少个数比它大,那么逆序对数就是 \(\sum\limits_{i=1}^n c_i\)

每一轮冒泡排序之后,每一个 \(c_i\) 都会减少且只减少 \(1\)

About 二分图完美匹配数量

这玩意儿的值实际上就等于邻接矩阵积和式的值。

上三角 / 下三角矩阵的积和式等于行列式。

对每条边随机一个权值求出行列式,如果结果 \(\ne 0\) 说明有完美匹配。

posted @ 2020-01-30 00:31  csxsi  阅读(9)  评论(0)    收藏  举报