分治 1

“Divide And Conquer”

把一个问题划分成几个相似子问题先求解
然后把这个子问题的解合并在一起
(一般还要依据子问题的解再做一遍求解)
这就是典型的分治思想——“分,治,合”
于是接下来就是最普通的分治:

归并排序&逆序对

分:递归左右子区间
治:(就是你在递归调用函数的时候相当于做了排序)
合:对于左右区间排好序的部分再进行一次合并
递归左右两边深度不超过logn所以时间复杂度O(nlogn)
Code:

点击查看代码
//远古码了应该是,这是个归并排序求逆序对的板子
//但是我不会修了
const int x=3000000+10;
int n;
int a[x],r[x];
long long ans;
void mergesort(int s,int t){
	int m,i,j,k;
	if(s==t){
		return;
	}
	m=(s+t)/2;
	mergesort(s,m);
	mergesort(m+1,t);
	i=s;
	j=m+1;
	k=s;
	while(i<=m&&j<=t){
		if(a[i]<=a[j]){
			r[k]=a[i];
			i++;
			k++;
		}
		else{
			r[k]=a[j];
			j++;
			k++;
			ans+=(m-i+1);
		}
	}
	while(i<=m){
		r[k]=a[i];
		i++;
		k++;
	}
	while(j<=t){
		r[k]=a[j];
		j++;
		k++;
	}
	for(int i=s;i<=t;i++){
		a[i]=r[i];
	}
}

快速幂

咱也不知道为啥就是分治
就是基于这么两个事情:

xaxbxa+b(modp),x2a(xa)2(modp)

很显然,因为原式在不取模状态下还是成立的
然后我们就看指数的情况,进行二进制划分
lowbit(b)表示b的二进制表示下最低位的1
然后对于我们的结果来说直接就乘上xlowbit(b)取模即可
Code

点击查看代码
//同样是远古码但是懒得修了
//虽然再写一版可能用不了多长时间
//Lucas板子差不多不超过5min吧
int work(int a,int b,int c){
	int ans=1;
	a=a%c;
	while(b>0){
		if(b&1){
			ans=(ans*a)%c;
		}
		b=b>>1;
		a=(a*a)%c;
	}
	return ans;
}

一般倍增就是和二进制划分结合起来的,时间复杂度会O(n)O(logn)

二分答案

二分答案是在函数保证有单调性的时候使用的
就是先猜一个答案,判定合法与否,合法就向更优方向靠近
首先在定义域上找两个点,取中值
然后把中值代入判定是否合法
如果合法向更优方向,不合法向合法方向更改区间范围
重复上述过程直到区间足够确定答案
框架:

点击查看代码
bool check(int mid){
	/*验证答案是否合法*/
}
int main(){
	/*其他东西*/
	int l=0,r=inf,ans;//左右端点和答案
	while(l<r){
        int mid=(l+r)/2;
        if(check(mid)){
            /*向更优方向移动*/
            ans=mid;
        }
        else{
           /*向合法方向移动*/
        }
    }
    ans=l;
    /*别的东西*/
}
posted @   2K22  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示