1快速排序
分两步,第一步找到基准值,第二部左右递归。
int getst(int arr[],int low,int high)
{
int key=arr[low];
while (low<high)
{
while(arr[high]>=key&&low<high)
{
high--;
}
if(low==high) break;
arr[low]=arr[high];
while (arr[low]<=key&&low<high)
{
low++;
}
if (low==high) break;
arr[high]=arr[low];
}
arr[low]=key;
return low;
}
void sort(int arr[],int low,int high)
{
if (low<high)
{
int t=getst(arr,low,high);
sort(arr,t+1,high);
sort(arr,low,t-1);
}
2.归并排序
void merge(int l,int mid,int r)
{
int i=l,j=mid+1;
int k=l;
while(i<=mid&&j<=r)
{
if (a[i]<a[j])
{
b[k++]=a[i];
i++;
}
else{
b[k++]=a[j];
j++;
cnt+=mid-i+1;//记录逆序对个数
}
}
while (i<=mid)
{
b[k++]=a[i];
i++;
}
while(j<=r)
{
b[k++]=a[j];
j++;
}
for (int ii=l;ii<=r;ii++)
{
a[ii]=b[ii];
}
}
void gbsort(int low,int high)
{
if (low<high)
{
int mid=(low+high)/2;
gbsort(low,mid);
gbsort(mid+1,high);
merge(low,mid,high);
}
}
3.单调队列维护
int l=1;
int r=1;//模拟队头和队尾
int ans=0;
q[1]=0;//q是一个存放下标的单调队列,保证sum【q【i】】单调
for (int i=1;i<=n;i++)//固定右端点,寻找左端点
{
while(l<=r&&q[l]<i-m) l++;
ans=max(ans,sum[i]-sum[q[l]]);
while(l<=r&&sum[q[r]]>=sum[i]) r--;//维护sum【q】的单调性
q[++r]=i;
}
4.kmp模式匹配
强烈建议将字符串首元素下标设为1,next【i】代表下标为i元素(包括i)的最大前后缀匹配长度
{
int slen=strlen(s1+1);
int plen=strlen(s2+1);
int j=0;
for (int i=1;i<=slen;i++)
{
while(j>0 && (j==plen||s1[i]!=s2[j+1]) ) j=next1[j];//没有大于0的话会陷入死循环
if (s1[i]==s2[j+1]) j++;
next2[i]=j;
if (next2[i]==plen)
{
result[++tot]=i-j+1;
}
}
}
void qn(char s[])
{
int len=strlen(s+1);
int j=0;
next1[1]=0;
for (int i=2;i<=len;i++)
{
while(j>0&&s[i]!=s[j+1]) j=next1[j];
if (s[i]==s[j+1]) j++;
next1[i]=j;
}
}
5.快速幂算法
while (n)
{
if(n&1)
{
x=a[0];
y=a[1];
z=a[2];
d=a[3];
a[0]=(x*b[0][0]+y*b[1][0]+z*b[2][0]+d*b[3][0])%mod;
a[1]=(x*b[0][1]+y*b[1][1]+z*b[2][1]+d*b[3][1])%mod;
a[2]=(x*b[0][2]+y*b[1][2]+z*b[2][2]+d*b[3][2])%mod;
a[3]=(x*b[0][3]+y*b[1][3]+z*b[2][3]+d*b[3][3])%mod;
}
memset(tmp,0,sizeof(tmp));
for (int i=0;i<4;i++)
for (int j=0;j<4;j++)
{
for (int ii=0;ii<4;ii++)
{
tmp[i][j]+=(b[i][ii]*b[ii][j])%mod;
}
}
for (int i=0;i<4;i++)
for (int j=0;j<4;j++) b[i][j]=tmp[i][j];
n=n/2;
}
本代码为矩阵快速幂,a可理解为常数,b为底数,n为指数,对n循环,n为奇数则提出与a相乘,偶数则不用。每一次循环都将b平方,达到logn的算法复杂度。
6.倍增算法
while (pp)//用于倍增的量
{
if (x+pp<y&&js(x+pp,y,z)<=k)若增加后满足条件
{
x+=pp;
pp<<=1;
}
else
{
pp>>=1;
}
}
对于一个单调递增序列,可以使用倍增快速找到小于x的最大值,