简 单 题
搞了一个月的机器学习,这段时间基本上没怎么碰过算法竞赛,所以咕了好久
最近重新回到算法竞赛里面,看了一些题目,觉得有必要再写(shui)一篇随笔
以后可能还会写一些关于机器学习的内容。虽然现在我只会扒拉别人的论文,但以后每个月都会抽出来连续的一周去搞机器学习,其他的时间就搞搞算法,水水学校的课(当然重要的课程还是要好好学),然后摸摸鱼
废话不多说,直接贴题目链接
https://www.luogu.com.cn/problem/P1972
简单来说就是给以一个长度为n的序列,m个区间查询,查询区间内有多少个不同的数
思路比较简单,树状数组,离线处理
把所有的询问按照右端点位置升序排列
考虑前r个数,对于每一个不同的数字,只把它所有出现位置 当中最右边的那一个标记为1,其他的全部是0
比如r=9序列
2 3 2 1 3 1 1 2 3 1 2 3 2 3 1 2 3 1
考虑前九个数,此时树状数组应该是这样的
0 0 0 0 0 0 1 1 1
对于所有的右端点为9的查询,直接在树状数组中求对应区间的和即可
为什么要这样做?对于所有重复的数,只保留最右边的,这样去重以后方便我们统计个数
而离线处理有方便我们对树状数组进行操作
这样一来,这道题就可以做了
从左到右扫一遍整个序列,同时对于每个数,用一个数组last[i]维护i上一次出现的位置(最靠右的i的位置)
当扫到第i个数a[i],就在树状数组中将i位置+1,同时将last[a[i]]减掉1,然后更新last数组,回答所有右端点在i的询问
这题就这么做出来了✿ヽ(°▽°)ノ✿
就这?
还有升级版P4113,换汤不换药
https://www.luogu.com.cn/problem/P4113
查询内容变了,P1972是查询出现次数大于等于1的数字的个数,P4113是查询出现次数大于1的数的个数
如果你理解了P1972,那么很容易就能想明白,在树状数组中把每一个不同的数的所有出现位置的"第二靠右"的位置标记为1,其它标为0即可
顺便给自己挖个坑,最近会更一篇动态开点线段树的教程

浙公网安备 33010602011771号