<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>分治 on Zirnc's Blog</title><link>https://blog.chungzh.cn/blog/%E5%88%86%E6%B2%BB/</link><description>Recent content in 分治 on Zirnc's Blog</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Sun, 30 Apr 2023 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.chungzh.cn/blog/%E5%88%86%E6%B2%BB/index.xml" rel="self" type="application/rss+xml"/><item><title>Luogu-P4755 Beautiful Pair</title><link>https://blog.chungzh.cn/oi-history/luogu-p4755/</link><pubDate>Sun, 30 Apr 2023 00:00:00 +0000</pubDate><guid>https://blog.chungzh.cn/oi-history/luogu-p4755/</guid><description>Luogu-P4755 Beautiful Pair
题意 小 D 有个数列 ${a}$，当一个数对 $(i,j)$（$i \le j$）满足 $a_i$ 和 $a_j$ 的积不大于 $a_i, a_{i+1}, \ldots, a_j$ 中的最大值时，小 D 认为这个数对是美丽的。请你求出美丽的数对的数量。
$1\le n\le{10}^5$，$1\le a_i\le{10}^9$。
编程时的问题 对 ST 表不熟悉！ 更 zz 的是，对 lower_bound 和 upper_bound 理解有问题，来复习一下小学知识：lower_bound 是找到“大于等于”的位置，upper_bound 是“大于”。写这道题的时候找小于某数的位置莫名其妙地用了 lower_bound，更没有 -1，完全是随手写的，半天也没察觉到这里有问题。 综上，我是 zz。
思路 考虑分治（据说这是套路），我们找出一个区间 $[l, r]$ 内的最大值位置 $mid$，然后统计所有跨过 $mid$ 的答案，再递归处理 $[l, mid-1], [mid+1, r]$。假设 $mid$ 左边的数是 $a_i$，右边的数是 $a_j$，根据题目得 $a_i * a_j \le a_{mid}$，即 $a_j \le \lfloor\frac{a_{mid}}{a_i}\rfloor$。那么我们枚举 $a_i$，然后用主席树统计右区间内小于 $\lfloor\frac{a_{mid}}{a_i}\rfloor$ 的数的个数。</description></item><item><title>CDQ 分治笔记</title><link>https://blog.chungzh.cn/oi-history/cdq-divide/</link><pubDate>Fri, 28 Apr 2023 00:00:00 +0000</pubDate><guid>https://blog.chungzh.cn/oi-history/cdq-divide/</guid><description>基本思想 CDQ 分治的基本思想十分简单。如下：
我们要解决一系列问题，这些问题一般包含修改和查询操作，可以把这些问题排成一个序列，用一个区间 $[L,R]$ 表示。 分。递归处理左边区间 $[L,M]$ 和右边区间 $[M+1,R]$ 的问题。 治。合并两个子问题，同时考虑到 $[L,M]$ 内的修改对 $[M+1,R]$ 内的查询产生的影响。即，用左边的子问题帮助解决右边的子问题。 这就是 CDQ 分治的基本思想。和普通分治不同的地方在于，普通分治在合并两个子问题的过程中，$[L,M]$ 内的问题不会对 $[M+1,R]$ 内的问题产生影响。
前置知识：二维偏序 给定 $N$ 个有序对 $(a,b)$，求对于每个 $(a,b)$，满足 $a2&amp;lt;a$ 且 $b2&amp;lt;b$ 的有序对 $(a2,b2)$ 有多少个。
可以将归并排序求逆序对的思路套用过来，这题实际上就是求顺序对。首先根据 $a$ 的大小排序，然后归并排序 $b$，这样就可以忽略 $a$ 元素的影响，因为左边区间的元素的 $a$ 一定小于右边元素的 $a$。归并排序时，每次从右边区间的有序序列取一个元素，然后求左边区间多少个元素比它小即可。
更浅显的解法是，用树状数组代替 CDQ 分治。这里就不赘述。
放个求逆序对的代码：
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 void mergesort(int l, int r) { if (l &amp;gt;= r) return ; int mid = (l+r)/2; mergesort(l, mid); mergesort(mid+1, r); int lp = l, rp = mid+1; int i = l; while (lp &amp;lt;= mid &amp;amp;&amp;amp; rp &amp;lt;= r) { if (a[lp] &amp;gt; a[rp]) { ans += mid-lp+1; b[i++] = a[rp++]; } else { b[i++] = a[lp++]; } } while (lp &amp;lt;= mid) b[i++] = a[lp++]; while (rp &amp;lt;= r) b[i++] = a[rp++]; for (int i = l; i &amp;lt;= r; i++) a[i] = b[i]; } 例题 一：三维偏序 Luogu-P3810 【模板】三维偏序（陌上花开）</description></item></channel></rss>