简 单 题

搞了一个月的机器学习,这段时间基本上没怎么碰过算法竞赛,所以咕了好久

最近重新回到算法竞赛里面,看了一些题目,觉得有必要再写(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即可

顺便给自己挖个坑,最近会更一篇动态开点线段树的教程

posted @ 2020-09-07 19:46  LMXZ  阅读(136)  评论(0)    收藏  举报