高斯消元数组
FFT/NTT数据结构
拉格朗日插值优化
LCTui
splayspa
K-D Tree指针
二分图/最大流/费用流code
后缀数组后缀自动机排序
总体二分递归
Polya定理队列
对于知足
\(f[i][j] = min(f[i][k], f[k + 1][j])\)的dp方程,猜测其知足四边形不等式
设\(s[i][j]\)表示\(f[i][j]\)取到最优值的决策点,有\(S[i][j - 1] \leqslant S[i][j] \leqslant S[i + 1][j]\)
转移状态不是太多的时候能够预处理全部有效状态
对于LCS这种每次只有一个会改变的dp能够记录差分以后的状态
数位dp + LIS 能够经过状压01来还原状态
对于一类有后效性的状压dp能够考虑SPFA
void insert(int x) { //if(mark[x]) return ; mark[x] = 1; for(int i = 0; i < 20; i++) if((x >> i & 1) && (!mark[x ^ (1 << i)])) insert(x ^ (1 << i)); }
for(int i = S; ; i = (i - 1) & S) { if(!i) break; }
所有访问->第一次访问
\[E(\max(S)) = \sum_{T \subseteq S} (-1)^{T + 1} E(\min(S))\]
统计全部\(i \& j = j\)的\(a[j]\)之和
实际上就是每次枚举一位而后算以前位的全部子集的贡献
for(int i = 0; i < B) {//必须先枚举这个 for(int j = 0; j < (1 << B); j++)//下标必须从0开始 if(j & (1 << i)) f[j] += f[j ^ (1 << i)]; }
一般是记录到达终止节点的指望步数
指望 = 权值 * 几率
发现指望dp中只与前一轮状态有关时能够矩乘优化
树上指望dp能够直接拆dp方程变成推系数的形式,先把叶子节点和非叶子节点拆开,发现1号节点不用从父亲转移过来从而解方程。
枚举子树dp的复杂度是\(O(n^2)\)
上面的dp若是是卷积形式能够用NTT优化
树形依赖背包能够用点分治+dfs序转移优化为\(n log n\),(不选直接从i+siz[i]+1的位置转移不然从i+1转移)
单调队列优化多重背包...我以为写不出来,到时候写二进制拆分吧。
能够二分一个权值,当选择一个数的时候加上该权值。这个时候可能还知足其余的单调性,也能够打表找一下[SDOI2016]征途
\(g[N]\)表示选了几个,更新答案的时候只须要在必定能够取到的点更新便可
while(l < r) { LL mid = l + r >> 1; check(mid); if(g[N] > M) l = mid + 1; else r = mid, ans = M * (f[N] - mid * M) - sqr(s[N]); }
考虑获得了询问点,如何构造出一棵虚树。
首先咱们要先对整棵树dfs一遍,求出他们的dfs序,而后对每一个节点以dfs序为关键字从小到大排序
同时维护一个栈,表示从根到栈顶元素这条链
假设当前要加入的节点为\(p\),栈顶元素为\(x = s[top]\),\(lca\)为他们的最近公共祖先
由于咱们是按照dfs序遍历,所以\(lca\)不多是\(p\)
那么如今会有两种状况
\(lca\)是\(x\),直接将\(p\)入栈。
\(x,p\)分别位于\(lca\)的两棵子树中,此时\(x\)这棵子树已经遍历完毕,(若是没有,即x的子树中还有一个未加入的点y,可是dfn[y]<dfn[p],即应先访问y), 咱们须要对其进行构建
设栈顶元素为\(x\),第二个元素为\(y\)
void insert(int x) { if(top == 1) {st[++top] = x; return ;} int lca = HLP::LCA(x, st[top]); if(lca == st[top]) {st[++top] = x; return ;} while(top > 1 && dfn[st[top - 1]] >= dfn[lca]) AE(st[top - 1], st[top]), top--; if(lca != st[top]) AE(lca, st[top]), st[top] = lca; st[++top] = x; }
sort(p + 1, p + K + 1, comp); for(int i = 1; i <= K; i++) { if(p[i] != 1) insert(p[i]); siz2[p[i]] = 1; } while(top > 1) AE(st[top - 1], st[top]), top--;
考虑把式子化成\(y = k x + b\)的形式
能够先用\(j > k\)且\(j\)比\(k\)优推出式子而后再考虑斜率/坐标是否单调。。
斜率单调:直接维护指针扫
斜率不单调:二分凸包
加入坐标单调:单调队列
加入坐标不单调:cdq
卷积形式\(f[i] = \sum_{j=1}^i {f[j] * f[i - j]}\)
对于要统计\(i - j\)的贡献的能够考虑翻转其中一个的下标变为\(i + (N - j)\)
含有通配符的字符串匹配问题能够构造多项式
基本不会,考到算倒霉。
若是有减法操做能够维护最大最小值,当除以一个数对于最大最小值产生的影响相同时改成减法运算
复杂度\(O(n \log^2 n)\)
维护区间\(and\)区间\(or\),若\(and\)上一个对两个标记的影响是相同的就改成区间加法(直接下传标记便可)。
记录区间最小值/次小值
若最小值\(\geqslant x\)则返回,不然若\(x\)大于最小值但小于次小值那么只考虑次小值的影响,不然暴力递归
复杂度\(O(n \log^2 n)\)
每一个点上加入一个直线,能够直接标记永久化,每次 下放较短的一段。
复杂度\(O(n \log^2 n)\)
主席树在某些状况下能够支持区间加1,这时候只须要维护区间值/被加的次数标记永久化便可
从一个点到根的重链不会超过\(\log n\)条,因此有时候能够暴力找出来搞事情。
空间开不下?
\(tan 90^o\)
unordered_map<int, unordered_map<int, int> > T;
这东西通常离线作比较稳,也就是从下往上合并的过程当中就把询问都处理掉
不然每次须要新建一个节点
考到认倒霉。。
记\(A\)为无向图的度数矩阵(A[i][i]表示\(i\)号点的度数),\(D\)为无向图的邻接矩阵\(D[i][j]\)表示\(i\)与\(j\)的边数
记\(G = A - D\),那么图的全部不一样的生成树等于任意一个\(n - 1\)阶主子式的行列式的绝对值
求行列式能够直接高斯消元后把主对角线上的全部元素乘起来复杂度\(O(n^3)\)
求\(a^x \equiv N \pmod P\)的最小的\(x\)
\(a^{i * k - j} \equiv N \pmod P\)
\(a^{i * k} \equiv N * a^j \pmod P\)
能够分为\(\sqrt{P}\)块暴力hash
当\(gcd(a, P) \not = 1\)时无解
\(f(n) = \frac{C_{2n}^n}{n + 1}\)
\(D(n) = (n - 1)(D(n - 2) + D(n - 1))\)
\(C_n^m \% P = C(n \% p, m \% p) * C(\frac{n}{p}, \frac{m}{p})\)
若是咱们要求\(\sum \frac{A_i}{B_i}\)最大
能够二分答案,咱们要求\(\sum \frac{A_i}{B_i} \geqslant K\)
\[\sum{A_i} - K(\sum B_i) \geqslant 0\]
也就是每选一个会产生\(A_i - K B_i\)的贡献
设\((a, b)\)为第一棵树中的直径端点,\((x, y)\)为第二棵树中的直径端点。
将这两棵树合并后的树的直径必定是\((a, x) (a, y) (b, x) (b, y)\)中的一个