1.排序算法
排序算法主要为快速排序,归并排序等八大排序。
归并排序其中一项应用为求逆序对。
快速排序:
void quick_sort(int q[],int l,int r)
{
if(l>=r)
return;
int x=q[l+r>>1];int i=l-1,j=r+1;
while(i<j)
{
do i++; while(q[i]<x);
do j--; while(q[j]>x);
if(i<j)
swap(q[i],q[j]);
}
quick_sort(q,l,j); quick_sort(q,j+1,r);
}
归并排序:res记录逆序对
int tmp[N];int res;
void merge_sort(int q[],int l,int r)
{
if(l>=r)
return;
int mid=l+r>>1;
merge_sort(q,l,mid);
merge_sort(q,mid+1,r);
int k=0,i=l,j=mid+1;
while(i<=mid&&j<=r)
{
if(q[i]<q[j]) tmp[k++]=q[i++];
else
{
tmp[k++]=q[j++];
res=mid-i+1;
}
}
while(i<=mid)
tmp[k++]=q[i++];
while(j<=r)
tmp[k++]=q[j++];
for(int i=l,j=0;i<=r;++i)
q[i]=tmp[j++];
}
2.二分
主要为整数二分,其中最主要为边界问题。
当 l=mid,int mid=l+r+1>>1.
当 l=mid+1,int mid=l+r>>1.
其余就是关于check函数的构造,和二分对象的选择
3.高精度
高精度加法等四则运算,用vector数组来进行运算,注意进位转化。
4.前缀和与差分
一维前缀和:s[i]=a[i]+s[i-1]
二维前缀和: s[i][j]=a[i][j]+s[i-1][j]+s[i][j-1]-s[i-1][j-1]
差分: 主要实现对原数组的差分矩阵,并且由基本运算差分矩阵前缀和即为对原数组进行运算后的新数组。主要分为一维差分和二维差分。
一维差分:s[l]+=c,s[r+1]-=c;
二维差分:s[x1][y1]+=c ;s[x2+1][y1]-=c;
s[x1][y2+1]-=c; s[x2+1][y2+1]+=c;
5.双指针算法
双指针算法是基于暴力枚举做法之下,根据题目所给条件的性质来进行优化将多重循环减少循环,比较考验思维性,一般做法先进行暴力枚举再进行优化。
for (int i = 0, j = 0; i < n; i ++ )
{
while (j < i && check(i, j)) j ++ ;
// 具体问题的逻辑
}
常见问题分类:
(1) 对于一个序列,用两个指针维护一段区间
(2) 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作
6.离散化,区间合并
主要应用于题目数据范围广且数据稀疏的情况下,实现数据与数组下标呈映射关系来处理问题。
将所要求的区间加入并去重,二分求出对应离散化的值,用数组长度作为二分区间。
7.位运算
求n的第k位数字: n >> k & 1
返回n的最后一位1:lowbit(n) = n & -n