高斯消元
FFT/NTT
拉格朗日插值
凸包
LCT
K-D Tree
可并堆/左偏树
线段树合并
整体二分
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]\)
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)];
}
可以二分一个权值,当选择一个数的时候加上该权值。这个时候可能还满足其他的单调性,也可以打表找一下[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
基本不会,考到算倒霉。
如果有减法操作可以维护最大最小值,当除以一个数对于最大最小值产生的影响相同时改为减法运算
复杂度\(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)\)中的一个