经验
1.无向图删边 使得每个点连接的边数为奇数 直接dfs即可
2.判断树上两条路径是否相交 LCA(u,v)在<x,y>上 或者 LCA(x,y)在<u,v>上
3.判断一个点x是否在路径(u,v)上 dp[LCA(u,v)]<=dp[x] 并且lca(x,u)=x||lca(x,v)=x
4.树上n条路径 选点集s 使得每条路径至少一个点在s中 最小化|s|
LCA深度排序 [贪心依次处理 满足深的可能满足浅的 但是满足浅的一定不满足深的]
5.n点m个边无向图初始所有边为白色 任意时刻与u相连的边中 有且仅有一条白色 这条变为白色 求最初染黑的边数最小值 使得最终都变黑
考虑如果是一棵树 花费为0 设最终连通块个数为C 当边数为n-c时 花费为0 所以初始边m-(n-c)
6.找两数异或最大 01trie树 同理区间异或最大 01trie树前缀异或和
7.区间[L,R](1e18)选两个数或最大 如果存在最高位i不同 ans=pow(2,i+1)-1 如果所有数的最高位都是1 则去掉这一位重复整个操作
8.树形dp背包第二维为选子树点数 在剪枝的情况下 n方的复杂度是可以满足的
9.三分只有在小数的时候能够找到具体的峰值 如果要求是整值 前后+1-1都要检查一遍
10.一棵树的哈密尔顿环 dis<u,v> <=3
如果是一条链 间隔一个连接 拓展到树上 如果深度为期数 dfs儿子前输出 如果深度为偶数 dfs儿子后输出
11.一个长度为n的序列 权值为ai 有m个区间 每个区间至少选一个ai 使得选择的Σai最小
如果区间存在包含关系 只用考虑小区间 这样按照顺序枚举右端点的时候 左端点一定是单调不减的 用单调队列优化dp
12.找u子树中 v在u儿子的子树的u的亲儿子 类似LCA往上跳
13.有根二叉树n个节点 再接一个点能选择的位置有n+1
考虑n个点原本能选择2n个位置 但是原本已经连接了n-1个位置 还剩n+1个位置能选
14.n个点的二叉树f[n] 卡特兰数 n个点的所有f[n]颗二叉树叶子节点总数g[n] g[n]=nf[n-1]
考虑f[n-1]课n-1点的二叉树 有n个位置能够插入一个新的叶子 每个叶子产生的贡献为f[n-1] 感性理解
15.1——>N M条边 选k个边使之变为0 求最短路 分层图 对每个点拆成k个点
16.维护最大次大 一定要先更新次大 再跟新最大!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- 树上m条不相交的路径 >=mid
f[u]表示以u为 终点/转折点 的道路数 f[u]+=f[v]
g[u]表示长度小于mid 向上延伸至u的长度
情况1 如果g[u]+w[i]>mid f[u]++
排除情况1的v 要使得两两组合>mid的对数最多
用multiset维护g[v] 从小到大进行lower_bound 因为我们要先尽可能想办法将较小的g[v]先利用起来!!!!
18.区间排序(升序降序) 求q点最终值
二分q点的最终值 大于等于q的设置为1 小于q的设置为0 区间升序 将后边都变为1 前边都变为0 同理降序 最终查询q点值即可
19.求长度范围在[L,R]内子串和的前K大值
用一个三元组<o,l,r>表示o为左端点 右端点在[l,r]内 维护一个堆 自定义sum[右端点]-sum[o]最大 右端点很明显可以用RMQ
对于每一个o [1,n] 放入三元组 这样能确保目前堆当中一定有前K大 太妙了!!!!
对于队首元素 找到mid 再将三元组<o,l,mid-1>和<o,mid+1,r>放入堆中
为什么这么做 因为对于每一个左端点 我们能依次找到以它为左端点的最优解
20.≤1e9的数中 质因数 最多只有10个
21.对于正数和负数的向上向下取整不可同日而语 两种操作不同
22.spfa有个vis数组 表示的是当前处于队内的元素 while到一个点u时 先将他出队 遍历他的后续时 如果不在队列中就入队
23.p(>2)为素数 1+2+3+....+p为p的倍数
24.1 4 9 16 差分 3 5 7 差分 2 2 2
25.k次操作获得的价值为序列与终值相同的数的个数(终值不定 个数包括终值) 每次操作可以将一个数+1或者-1
排序完以后很明显就是一段连续的区间 考虑一个区间怎样才能最小化操作次数达到目的 很明显要选择其中的中位数(初中知识)
这样只需要区间双指针尺取法O(n)因为对于每一个左端点 其满足条件的右端点是递增的!!!
26.// 一些差分约束的规则
// s[b]-s[a]<=k
// s[b]-s[a]>=k ----> s[a]-s[b]<=-k
// s[b]<=s[a]+k a-b:k
// s[a]<=s[b]-k b-a:-k
// s[a]-s[b]==k ---->s[a]-s[b]<=k && s[a]-s[b]>=k
// s[a]-s[b]<k ---->s[a]-s[b]<=k-1
// 前缀和dis 还要保证 dis[i]-dis[i-1]>=0
//如果数列s每项<=1 还要dis[i]-dis[i-1]<=1
a[i][j]冒泡排序
for(int i=1;i<=n;++i)
{
int p=i;
for(int j=i+1;j<=n;++j)
if(a[j][1]<a[p][1]) p=j;
if(i!=p)hc++,swap(a[i],a[p]);//可以直接交换二维数组的两行
}
28.多数据初始化的时候 不要用memset 容易超时
29.n个数最大值为v的情况为fast_mi(v,n)-fast_mi(v-1,n)
30.按位与操作 想到高维前缀和
31.计算n!末尾0的个数 考虑分别5的1次 5的2次....5的k次的个数之和 不用考虑2
32.判断四边形是否有内切圆:对边和相等
33.求区间[L,R]有多少个数是k的倍数,R/k - (L-1)/k

浙公网安备 33010602011771号