总结一些最近见到的 TRICK

总结一些最近见到的 TRICK

  1. 并查集 O ( n + m ) O(n+m) O(n+m) 解决区间合并问题 3115. 疯狂的馒头

  2. 滑动窗口枚举到 i i i 点时求 [ i − k , i − j ] [i-k,i-j] [ik,ij] 中的最值。

  3. 单调栈求距离自身最近的最右的某个值需要倒序。

  4. 枚举矩阵有 4 个自由度,可以通过枚举上下两个边界将矩阵变成 1 维的,在用二分或双指针实现 O ( n 3 ) O(n^3) O(n3) 遍历。

  5. 给定一个 n ∗ m n*m nm 的矩阵 求一个 c ∗ c c*c cc 大小的子矩阵中的最值。可以用二维滑动窗口实现。核心思路还是二维看成一维。先每一行求一个长度为 c c c 的滑动窗口,在每一列求一个长度为 c c c 的滑动窗口,最后枚举答案。

  6. DP的本质是组合数学,可以通过0/1背包,完全背包的思路推导组合数学中组合数公式和可重集组合公式。

  7. 区间合并问题要记住一些智慧数据,区间合并可以 O ( n ) O(n) O(n) 实现,左端点从小到大排序。

  8. unorder_map,均摊 O ( 1 ) , 最坏 O ( n ) O(1),最坏O(n) O(1),最坏O(n) , 快排是均摊 O ( n l o g n ) , 最坏 O ( n 2 ) O(nlogn),最坏O(n^2) O(nlogn),最坏O(n2)可以通过初始化大小防止被卡,(CF除外,需要mt19937)

  9. 区间合并有3种做法,并查集,贪心,离散化+差分。

  10. 刷表法可以求解背包问题 K K K 优解。

  11. 给定一个矩阵,求带限制的最大的子矩阵的面积,还是每一行单独考虑,跑 n n n单调栈

  12. 给一堆东西染色求最后的颜色,可以倒着考虑。

  13. 很多求树上问题的思路来源都是 树的重心 还有 树的直径

  14. 许多问题要逐步分解,如果没有思路,可以尝试,画图找规律和性质,二分答案转成判定,等

  15. 双指针关键(其实写多了就没啥关键不关键的了),定义 j = f [ i ] j = f[i] j=f[i] , 如果 i i i 确定之后, j j j 只能单调向左(没见过)/右移动,就可以直接双指针了。while循环里边是否定条件。

  16. 矩阵上求最值除了求 n n n 遍单调队列还可以二维 S T ST ST 表。

  17. 线段树指针写法,new 超慢,可以定义静态的节点再用一个移动一位。

  18. L C A LCA LCA t a r j a n tarjan tarjan ,并查集,倍增 三种写法, 至少会背一个。

  19. 如果两个区间 [ l 1 , R 1 ] , [ R 1 + 1 , R 2 ] [l_1,R_1],[R_1+1,R_2] [l1,R1],[R1+1,R2] 想多空一个间隔,可以下标乘2。 有点sb

  20. 二维一维化可以传二维数组的一维进去,但是要是按照列来做呢?要么重写一个,要么把数据先按照列拿出来,再传进去。

  21. 有的时候我会把DP状态表示的太死,然后发现状态转移方程完全写不出来,可以退一步,让DP多带一维信息,再试试。比如,一定选,一定不选。

  22. 可行性DP,可以用 bitset 装逼实现。

  23. 一些已知中序遍历和xx遍历,输出bfs序的题,在dfs里边穿一个层,就能直接记录下bfs序。
    笛卡尔树

  24. 又学到了一个非常常用的TRICK。就是给定 M M M 次染色序列,问最后所有位置的颜色是什么。如果从前向后考虑,后边的染色会覆盖之前的一种染色,可以倒着考虑,如果一段区间 已经 染色就不再被染色了 (每个位置只会被染色一次) ,然后跳过一些状态,进行优化。3115. 疯狂的馒头

  25. 如果有double精度问题,比如保留1位小数,可以先*10再/10。

  26. 实数二分,比如要算距离,可以每次判断都不开方,最后开方保证精度。

  27. 大于等于 a a a 的第一个 b b b 的倍数 = ⌈ a b ⌉ ∗ b = \lceil \frac{a}{b} \rceil *b= bab= a + b − 1 b ∗ b \frac{a+b-1}{b}*b ba+b1b 集合 ,质数距离中也有这个东西。

  28. 如果有置换的题目,可以通过各个点连边找环解决。F. Shifting String

  29. 求n个数的gcd,lcm,lcm的幺元是1,可以直接将一个数组中的数全都乘起来。gcd需要先拿一个数。

  30. 开二维数组,只给定乘积的方法: 2 ≤ n ⋅ m ≤ 1 0 5 2≤n⋅m≤10^5 2nm105

cin>>n>>m;
vector<vector<int>>g(n,vector<int>(m)); // n*m的动态矩阵
for(int i=0;i<n;i++){
   for(int j=0;j<m;j++){
   	cin>>g[i][j]; // 不要用push_back,会出错
   }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值