记录一些个人遇到的有用的知识,持续更新
STL相关
1、二分查找:lower_bound和upper_bound
lower_bound( begin,end,num):
从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num):
从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
lower_bound( begin,end,num,greater<type>() ):
从数组的begin位置到end-1位置二分查找第一个小于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num,greater<type>() ):
从数组的begin位置到end-1位置二分查找第一个小于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
KMP
1、字符数组A[ ]的长度为n,KMP处理后的序列为p[ ],那么字符串的最短循环字串长度为n-p[ n ],
最长公共前后缀为p[ n ]。
树状数组
1、lowbit()计算一个非负整数n在二进制下的最低为1及其后面的0构成的数。
方法是,将n取反,再加1,阔以得到-n,此时n&(-n)就是lowbit得到的数字
例如1010 取反---> 0101 加1---> 0110 所以n&(-n)=0010。
2、树状数组中节点x的父节点为x+lowbit(x),例如t[2]的父节点为t[4]=t[2+lowbit(2)]
动态规划
1、Dilworth 定理
狄尔沃斯定理亦称偏序集分解定理,该定理断言:对于任意有限偏序集,其最大反链中元素的数目必等于最小链划分中链的数目。此定理的对偶形式亦真,它断言:对于任意有限偏序集,其最长链中元素的数目必等于其最小反链划分中反链的数目。
人话:划分原序列的LDS数目必定等同于原序列中的LIS长度
2、LIS:最长不下降子序列
LDS:最长不上升子序列
3、LIS、LDS的优化 O(NlogN):
设数组 d 表示 当前 的最长不下降子序列, len 表示其长度。那么 d[len] 就表示当前子序列的最后一个元素。
一开始 len=1,dlen=a1,之后开始向后遍历,考虑当前遍历到的 ai :
- 若 ai≥dlen ,则直接放入 d 的末尾
- 若 ai<dlen ,则在 d 中找到第一个大于它的数,插入进去,并丢弃在他之后的元素
上升子序列元素不能重复,二分优化是用lower_bound,不下降子序列用upper_bound
字符串
1、比较s1 s2 两个字符串哪个对字典序贡献更大,可以比较s1+s2, s2+s1两个字符串,防止位数不同出现的错误,例题见拼数.
数学
进制
1、C++中 -15/(-2)=7 -15%(-2)=-1 与数学中的不一样,要正确求解负数取模的话,将商+1,被除数-商乘以除数
-15 % (-2) = -15-(7+1)*(-2)=1;
位运算
1、任何书与0异或都为其本身
2、k 个相同的数的异或和,当 k 为奇数时,结果是这个数本身,否则结果是 0。