排序
快速排序
取数组中间的数x为基准,将数组分为 <=x 和 >=x 小两部分。对分好的两部分数组递归运行上述操作。
void quick_sort(int * a, int l, int r)
{
if(l >= r) return;
int x = a[(l + r) >> 1], i = l - 1, j = r + 1;
while(i < j)
{
do(i ++) ; while(a[i] < x);
do(j --) ; while(a[j] > x);
if(i < j) swap(a[i], a[j]);
}
quick_sort(a, l, j);
quick_sort(a, j + 1, r);
}
归并排序
void merge_sort(int * a, int l, int r)
{
static int temp[N];
if(l >= r) return;
int mid = l + r >> 1;
merge_sort(a, l, mid);
merge_sort(a, mid + 1, r);
int i = l, j = mid + 1, k = 0;
while(i <= mid && j <= r)
{
if(a[i] <= a[j]) temp[k ++] = a[i ++];
else
{
// 求逆序对的数目加入下一行代码
//res += mid - i + 1;
temp[k ++] = a[j ++];
}
}
while(i <= mid) temp[k ++] = a[i ++];
while(j <= r) temp[k ++] = a[j ++];
for(int i = l; i <= r; i ++)
a[i] = temp[i - l];
}
二分查找
整数二分
//解在右半部分左边界
int l = 0, r = n - 1;
while(l < r)
{
int mid = l + r >> 1;
if(check(mid)) r = mid;
else l = mid + 1;
}
//解在左半部分右边界
int l = 0, r = n - 1;
while(l < r)
{
int mid = l + r + 1 >> 1;
if(check(mid)) l = mid;
else r = mid - 1;
}
浮点二分
double l = 0, r = n;
while(fabs(l - r) > 1e-8)
{
double mid = (l + r) / 2;
if(check(mid)) l = mid;
else r = mid;
}
高精度
高精度加法
vector<int> add(vector<int> & a, vector<int> & b)
{
vector<int> c;
int t = 0;
for(int i = 0; i < a.size() || i < b.size(); i ++)
{
if(i < a.size()) t += a[i];
if(i < b.size()) t += b[i];
c.push_back(t % 10);
t /= 10;
}
if(t) c.push_back(t);
return c;
}
高精度减法
//a > b 返回true
bool cmp(vector<int> & a, vector<int> & b)
{
// 由高位向低位逐位比较
if(a.size() == b.size())
for(int i = a.size() - 1; i >= 0; i --)
if(a[i] != b[i])
return a[i] > b[i];
return a.size() > b.size();
}
vector<int> sub(vector<int> & a, vector<int> & b)
{
vector<int> c;
int t = 0;
for(int i = 0; i < a.size(); i ++)
{
t += a[i];
if(i < b.size()) t -= b[i];
c.push_back((t + 10) % 10);
if(t < 0) t = -1;
else t = 0;
}
while(c.size() > 1 && c.back() == 0) c.pop_back();
return c;
}
高精度乘法
// a * b
// a为大数 b为小数
vector<int> mul(vector<int> & a, int b)
{
vector<int> c;
int t = 0;
for(int i = 0; i < a.size(); i ++)
{
t += a[i] * b;
c.push_back(t % 10);
t /= 10;
}
while(t) c.push_back(t % 10), t /= 10;
while(c.size() > 1 && c.back() == 0) c.pop_back();
return c;
}
高精度除法
// a / b
// a为大数 b为小数
// 计算商和余数
vector<int> div(vector<int> & a, int b, int & r)
{
vector<int> c;
r = 0;
// 从高位开始计算
for(int i = a.size() - 1; i >= 0; i --)
{
r = r * 10 + a[i];
c.push_back(r / b);
//注意是 >=
if(r >= b) r %= b;
}
reverse(c.begin(), c.end());
while(c.size() && c.back() == 0) c.pop_back();
if(c.empty()) c.push_back(0);
return c;
}