[{"content":"这里是一名计算机专业的大学生！想在这里记录并整理一些自己学到的知识\n很多基本是刚开始学并且学习的内容可能比较杂，如果有错还望海涵❤️，提前感谢帮忙纠错的大佬\n主页的成分可能会比较复杂（目移）\n","date":"2026-03-27T00:00:00Z","image":"/post/test-post/cover.jpg","permalink":"/post/test-post/","title":"初次见面！"},{"content":"关于离散化的一些笔记\n学习参考https://www.cnblogs.com/cytus/p/8933597.html\n尝试用自己的话梳理一下\n离散化 如果我们遇到一道题，已知里面有很多个可重复的数，不同的数最多有100种，范围在1~10^12不等。我们需要记录每个数出现的次数，但是分配的内存空间不允许我们直接开10^12这么大的数组，所以出现的数本身无法作为下标。这个时候如果题目中数仅相对大小存在意义，我们就可以将它们进行离散化处理之后再用100的数组来储存。\n比如数组{3,6,1,9}离散化之后处理为{1,2,0,3}\n处理之后范围更小的数常用来做数组下标，在并查集、线段树等情境下也有应用\n写的时候突然想到，如果是小数等不允许被用来做下标的元素，条件允许的话也可以用离散化只存储相对大小\n流程如下：\n通用方法 一、复制数组 首先假设我们拥有一个输入的数组，数组中的数本身不允许我们用来直接做下标。我们先用数组a把他们的值存起来，然后复制一份到数组t。\n为方便去重，我们使用从0开始的下标。\n作为例子，我们假设数最多有n种，数的范围最大为10^9 （方便写int） ，那么现在我们有：\nvector\u0026lt;int\u0026gt; a; vector\u0026lt;int\u0026gt; t = a;//与a数组内容相同 二、数组排序并去重（视情况） 如果输入的数组中没有重复元素，直接使用sort进行排序即可：\nsort(t.begin(),t.end());//默认升序 如果输入的数组中有重复元素，我们就需要先进行排序，再进行复制数组中的去重。\n不去重会导致离散化编号之间存在空缺，造成浪费。\n我们使用unique函数对复制之后的数组t进行去重：\nunique用法：unique(t.begin(), t.end())，返回去重后数组的尾地址的后一格。unique在被使用后会将不重复元素依次移到前面，因此不会打乱原来的排序。同时，后面的不需要的重复元素需要用erase清除。\nsort(t.begin(),t.end());//先进行升序排序 t.erase(unique(t.begin(),t.end()),t.end());//先执行unique再执行erase 三、离散化处理进入新数组 t数组已经排序并且没有重复元素，此时t数组的下标的相对大小与元素的相对大小一样，并且下标数据小没有空间浪费，我们就可以让t数组的下标成为对应元素的离散化编号。\n问题来了，我们发现t数组中的元素的顺序和a数组不一样了，同时重复的元素也没有了，很显然无法直接作为处理后的a数组来进行使用。那我们应该怎么把原数组a中的元素用他们相应的离散化编号来替代并存入新的数组呢？\n（这里可以将离散化编号直接塞回原数组a）\n四、lower_bound二分查找的办法（通用） 原理是按照a数组的下标从小到大去看，去找a数组数据在t中的位置，将t对应的位置下标存入新数组的a数组对应的下标中。我们之前已经知道了，t数组中数据的位置就是他们的离散化编号。\n流程大概是这样的：\na[x] -\u0026gt; lower_bound发现t[y] = a[x] -\u0026gt; result[x] = y\n有代码：\nvector\u0026lt;int\u0026gt; result(n); for(int i = 0; i \u0026lt; n; i++ ) { result[i] = lower_bound(t.begin(),t.end(),a[i]) - t.begin(); } 补充方法：用pair事先保存原下标（不需要t数组，简单版本无法处理元素重复的情况） 我们直接从一开始的a数组开始处理即可。这种方法不用普通的t数组，而是使用pair数组作为辅助数组。\n这种方法的思路是在存储原值的同时，也保存这个值在原数组中的下标。这样可以替代方法一中搜索的过程。这种方法因为省去了二分查找的过程直接写回所以速度较快，但是下面给出的是简单版本，不能直接处理重复元素。此处我们使用pair存储之后会直接排序，把顺序当做离散化编号，不会去重。\n有重复元素的话，遍历values遇到重复元素就特殊处理一下（如果当前元素的first和前一个元素相同，就让它继续使用前一个元素的离散化编号；如果不同，编号才加一。）的写法也可以。\n这种方法需要建一个新的pair数组values，根据原数组a来存储原值和原下标。\nvector\u0026lt;pair\u0026lt;int,int\u0026gt;\u0026gt; values; for(int i = 0; i \u0026lt; n; i++ ) { values.push_back({a[i] , i}); } 我们依据values存储的原下标和原值的对应关系来进行操作。流程：\nvalues按照first排序 -\u0026gt; y是离散化编号 -\u0026gt; values[y].second是该元素的原下标 -\u0026gt; result[values[y].second] = y\nsort(values.begin(),values.end());//pair数组默认按pair的前值升序排序 for(int i = 0; i \u0026lt; n; i++ ) { result[values[i].second] = i;//将序号，即离散化编号赋值给结果数组原下标的位置，使离散化编号i替代相应的原值 } 自此，离散化完成。我们从原数组a得到了新的结果数组result，现在我们可以使用result数组中的较小的元素在我们需要的地方作为下标了。\n","date":"2026-10-19T00:00:00Z","image":"/post/acmplan-%E7%A6%BB%E6%95%A3%E5%8C%96/omori.jpg","permalink":"/post/acmplan-%E7%A6%BB%E6%95%A3%E5%8C%96/","title":"离散化"}]