algorithm_know
2.16
降低时间复杂度的方法(降低运行时间防止超时)
使用平方根去约束数的循环范围
应用场景:完全数,质数
前缀和
得到某一段数组 [l,r] 的和,常规循环计算的复杂度为 O(n) ,使用前缀和就可以直接使用 S(r) - S(l-1) ,复杂度为O(1)
差分
树状数组
- O(log)的时间复杂度去实现单点修改和区间查询
- 数组下标一定要从1开始
- 一个数的二进制表示中末尾有几个0就在第几层
2.17
位运算
求 n 的二进制表示的第 k+1 位(计数从1开始)数字:
n >> k & 1
n & 1
判断第1位的数字
1 |
|
返回 n 的最后一位1所对应的值:lowbit(n) = n & -n = n & (n^(n-1))
假设一个数的二进制最低位的1在从右往左数的第k位,那么它的lowbit值就是2^(k-1)
树状数组C[x] = [x-lowbit(n) , x] 原数组中这段区间的和
3.25
n次方幂
1 |
|
3.26
线段数组
tips
- 线段树是一棵平衡二叉树。母结点代表整个区间的和,越往下区间越小
- 每个节点p的左右子节点的编号分别为 2p 和 2p+1
- 节点p存储区间[l,r]的和,设 mid = floor(l+r/2) ; 左节点存储[l,mid]的和, 左节点存储[mid+1,r]的和
建立线段数组
1 |
|
区间查询
把区间内的叶子节点相加
单点修改
第k小数
1 |
|
二分查找
首先,binary_search()函数,作用:对一个不降序列进行二分查找,如果所查找的值在序列中出现了,返回true,没有出现,返回false。
然后,lower_bound()函数,作用:对一个不降序列进行二分查找,返回第一个大于等于所查找的值的元素下标,注意返回的是指针变量!!!
最后,upper_bound()函数,作用:对一个不降序列进行二分查找,返回第一个大于所查找的值的元素下标,注意返回的是指针变量!!!
无穷大和无穷小
指定一个数为无穷大或无穷小:INT_MIX INT_MAX
要把一段内存全部置为无穷大,我们只需要memset(a,0x3f,sizeof(a))
要把一段内存全部置为无穷小,我们只需要memset(a,0xc0,sizeof(a))
map
map[key] = value
查找map中某个key是否存在/具体位置
mp.count(key)
查看元素是否存在,因为map中键是唯一的,所以存在返回1,不存在返回0
mp.find(key)
返回键为key的映射的迭代器 $O(logN) $ 注意:用find函数来定位数据出现位置,它返回一个迭代器。当数据存在时,返回数据所在位置的迭代器,数据不存在时,返回mp.end()
set
set里面的元素不重复 且 有序
如何将字符串转换成数字
String str=“2019”;
char s[]=str.toCharArray();
int x=0;
for(int i=0;i<s.length;i++){
x=x*10+str[i]-‘0’;
}
结构体数组排序
当数组是从1开始赋值时,sort函数也要加1
1 |
|
1 |
|
max_element+min_element
返回最大最小值的下标所对应的地址
1 |
|