第282场周赛
链接↓
算法板子目录
1 | string add(string a, string b) { |
1 | #include<bits/stdc++.h> |
整数二分步骤:
1.找一个区间[L,R],使得答案一定在该区间中
2.找一个判断条件,使得该判断条件具有二段性,并且答案一定是该二段性的分界点。
3.分析终点M在该判断条件下是否成立,如果成立,考虑答案在那个区间;如果不成立,考虑答案在那个区间;
4.如果更新方式写的是R = Mid, 则不用做任何处理;如果更新方式写的是L = Mid,则需要在计算Mid时加上1。
写法一
当我们将区间[l, r]划分成[l, mid]和[mid + 1, r]时,其更新操作是r = mid或者l = mid + 1;,计算mid时不需要加1。
1 | int bsearch_1(int l, int r) |
写法二
当我们将区间[l, r]划分成[l, mid - 1]和[mid, r]时,其更新操作是r = mid - 1或者l = mid;,此时为了防止死循环,计算mid时需要加1。
1 | int bsearch_2(int l, int r) |
更新:
删去了其他比较trivial的排序,留下了算法竞赛中用的略微多的排序思维。
删掉了useless的排序方法(希尔等等)。
修正了代码语言,Java语言由于当时第一版所写的错误过多,因而删除,再加上在运行速度上不及C++。
是一种基于分治的排序方法。
对需要排序的区间[l,r]进行下面的操作:
(1) 如果区间长度小于等于1直接退出,否则在区间中选择一个数字x作为比较元素。
(2) 将大于x的数字放右边,小于x的数字放左边,等于x的可左可右,将x放在两组数字中间。
**(3)**此时x的位置确认,对其左右两边的区间分别进行递归即可。
1 | void quicksort(int l,int r) { |
是一种基于分治的排序方法。
对需要排序的区间[l,r]进行下面的操作:
(1) 如果区间长度小于等于1直接退出,否则将区间分为[l,m],[m + 1,r]两个部分,其中 m = (l + r) / 2。
(2) 递归对两个子区间进行归并排序。
(3) 将两个已经排好序的子区间进行合并。
1 | void mergesort(int l,int r) { |
计数排序适合于值域范围校的数字排序
(1) 统计每个数字出现了几次。
(2) 统计完每个元素的出现次数后,求一边前缀和,我们就知道了每个数字在排完序后的序列中出现位置的范围。
(3) 把数字填入对应的位置即可。
1 | #define endl "\n" |
将每个待排序的元素拆分成m个关键字,然后从后往前依次对这m个关键字进行排序。
特别的
(基数排序经常被用于进行字符串的排序,比如说后缀数组的核心就是基数排序)。
(1) 我们只要把数字按第 i 个及以后的关键字从小到大的顺序放到数组里,再做一次计数排序就好。
1 | int n, m, a[N + 1], sa[N + 1], v[N + 1], r[N + 1], c[10]; |