经验

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.维护最大次大 一定要先更新次大 再跟新最大!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

  1. 树上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

posted @ 2022-11-03 16:43  wzx_believer  阅读(107)  评论(0)    收藏  举报