首页 > 其他分享 >分治

分治

时间:2025-01-15 20:12:20浏览次数:1  
标签:return randint int 分治 问题 细节 分解

1.解释

把一个问题分解成多个不同子问题,当子问题可以迎刃而解时,整个问题也就迎刃而解

优点:可以将复杂的问题简单化,让问题更好解决

缺点:很容易扣细节就绕进去了,很难使人相信这东西的正确性

2.步骤

分而治之


1.尝试去分解问题(最难的一步)

2.不断分解直到没法继续分解

3.利用简单的求复杂的


因为这一段实在是 难理解。所以我配两个例子

1.斐波那契数列

天坑

我学会证明就来填

2.线段树

其实这个很简单。就是把一段分解成左和右,在继续分解左右的左右

3.例题

将读入的 \(N\) 个数从小到大排序后输出。

思路:不断分解几个数,分割为左部分和右部分(对应分解),然后没法分解时再比较相邻左子树右子树上的两个数大小,合并,就轻而易举的解决了(归并排序)

代码:

// 注:四个数组的下标均从 0 开始。
// 请在主函数内设置随机种子,例如 srand(time(0)),否则可能会超时。
int randint(int l, int r){ // 生成在 [l, r] 之间的随机数
	return rand() % (r - l + 1) + l;
}
void qsort(int l, int r){ // l 为左端点,r 为右端点
	if(l >= r){ // 如果长度为 0 或 1 就返回
		return;
	}
	int num = randint(l, r), ind1 = 0, ind2 = 0, ind3 = 0; // 随机选择一个数,并定义三个作为下标的变量来记录长度、存放数据
	for(int i = l;i <= r;i++){ // 将 a 中的数分别分到 b, c, d(如上所述)
		if(a[i] < a[num]){
			b[ind1++] = a[i];
		}
		else if(a[i] == a[num]){
			c[ind2++] = a[i];
		}
		else{
			d[ind3++] = a[i];
		}
	}
	for(int i = 0;i < ind1;i++){ // 将 b, c, d 中的数重新放回 a
		a[i + l] = b[i];
	}
	for(int i = 0;i < ind2;i++){
		a[i + ind1 + l] = c[i];
	}
	for(int i = 0;i < ind3;i++){
		a[i + ind1 + ind2 + l] = d[i];
	}
	qsort(l, l + ind1 - 1); // 继续递归,排序原来的 b 和 d
	qsort(l + ind1 + ind2, r);
}

by lg大神@Allen_123

4.技巧

明白一个函数的作用并相信它能完成这个任务,千万不要跳进这个函数里面企图探究更多细节, 否则就会陷入无穷的细节无法自拔。

这里有个亲身经历



作者在考今年\(CSP\)时\(T2\)打了个\(DFS\),在写\(DF\)S时我就一直在想他递归到最后是什么样子的,耽误了\(1h\)!!!

永远相信自己的第一写法是对的 永远

标签:return,randint,int,分治,问题,细节,分解
From: https://www.cnblogs.com/March7thDev/p/18673657

相关文章

  • 点分治&&点分树
    点分治前置芝士:树的重心树的重心指对于一棵无根树上的一点,其分割开的若干子树大小的最大值最小。一般用DFS求解树的重心。初始时,\(\mathit{mxs}=\mathit{sum}=n\),即树的节点个数。最终的\(\mathit{rt}\)即为重心。voidgetrt(intu,intfno){ ints=0; siz[u]=1; for(i......
  • 分治的思想
    分治算法是一种很重要的算法策略,它的基本思想是将一个复杂的问题分解成更多相同或相似的子问题,所以分治算法通常以递归的方式实现。就像之前讲的归并排序(不知道可以翻翻之前的博客),将排序的过程不断拆解,排n个数可以排两个n/2个数,看做排n/2再/2,排4段数,最后可以看做排n段长度......
  • 线段树分治-学习笔记
    线段树分治-学习笔记阅前须知:本文给出了线段树分治的一道例题以及多道习题,同时给出了部分实现的代码,帮助学习线段树分治。总述线段树分治是一种离线算法,在于把修改挂在线段树的节点上,通过遍历线段树求出每个叶子节点的答案,以减小复杂度。例题P5787二分图题目大意:\(n\)个点......
  • 点分治
    更新日志2025/01/07:开工。概念点分治,通常用于处理大规模的树上路径信息问题。思路我们将原问题划分为多种,对于每个节点,统计经过这个节点且位于这棵子树内的路径答案。为了缩减复杂度,对于每一棵子树,我们都找到它的重心,以重心为新根在子树内进行操作。找重心示例:intcn......
  • 分治杂记
    分治杂记分治(DivideandConquer),就是把一个复杂的问题分成若干子问题,分别求解。本质是缩小了问题的规模。普通的分治[ABC373G]NoCrossMatching给定平面上的\(n\)个黑点和\(n\)个白点,构造一种方案,将黑白点两两匹配并连线段,使得任意两条线段不相交。\(n\leq100\),保......
  • 深入了解分治 FFT
    问题提出算法应用于问题,分治FFT的出现是为了解决这样一个问题:给定序列\(g_{1\dotsn-1}\),求序列\(f_{0\dotsn-1}\)。其中\(f_i=\sum_{j=1}^if_{i-j}g_j\),边界为\(f_0=1\)。具体可以见【模板】分治FFT-洛谷对于这个问题我们要求做到\(\Theta(n\log^2n)\)的......
  • 【优选算法 & 分治】深入理解分治算法:分治算法入门小专题详解
             快速排序算法   (1)快速排序法       (2) 快排前后指针     (3)快排挖坑法   颜色分类  题目解析    算法原理   算法原理和移动零非常相似  简述移动零的算法原理   ......
  • [学习笔记] 根号分治
    https://www.cnblogs.com/guanlexiangfan/p/15553329.htmlhttps://blog.csdn.net/qq_35684989/article/details/127190872放一下讲得比较好的根号分治。根号分治,一般将数据分为\(a<\sqrtn\)的与\(a>\sqrtn\)的进行分类讨论。一般可以配合预处理将\(O(n^2)\)的做法优化......
  • 分治策略——算法学习(二)
    分治策略——算法学习(二)前言在算法设计的世界中,分治策略(DivideandConquer)是一种极具魅力的思想,它通过将复杂问题拆解为多个规模较小但结构类似的子问题,从而以递归的方式解决问题。这种策略不仅高效而且直观,为许多经典算法的诞生奠定了基础,如快速排序(QuickSort)、归并排序(Merg......
  • 分治总结
    有各种分治:CDQ分治,树上分治,数据结构上分治,根号分治,etc.普通分治求逆序对用归并排序求逆序对。Sol:其实逆序对是在归并排序时顺带求的,主要是归并排序。我们要对区间\([l,r]\)从小到大排序,先对\([l,mid],[mid+1,r]\)排序(这一步体现分治思想)。现在考虑怎么把两边合并。我们定义......