c++笔记

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的最大值,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

19lrf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值