深蓝的新硬盘:莫队算法初步

来源:互联网 发布:java培训四月 编辑:程序博客网 时间:2024/05/16 12:36

(写这篇之前必须先orz一波莫涛队长)

话说深蓝跟着Ration这么久了,也付出了这么多,Ration决定满足深蓝的一个愿望。

Ration:你要啥?

深蓝:(歪头)EMMMMMM……自然是移动硬盘啦OVO,人家内存本来就不大,你还往里装那种东西(捂脸)

Ration:哈?

深蓝:别歪想,是.cpp。

Ration:好吧……(移动硬盘好贵啊QAQ)

——————————————————

电脑配件商店里。

深蓝:哇好多硬盘啊!!!老板老板,快把它们排开,我要这个,这个,这个……

老板:好好好,女士您别急。

Ration:然而我积分点不多啊……(心生一计)那么,我多给你买几个好不好?

深蓝:主人最棒啦!!!QWQ

Ration:老板,请把这些移动硬盘按照价格排好。

老板:好啦!

Ration:接下来我会给出一些价格段,每个段里如果你说出有多少种不同的牌子,就可以可以买一款你最喜欢的。

深蓝:自然是性能最好的啦OVO

Ration:嗯。但是,你必须在 (N*log(N*N)+N*sqrt(N)*log(N))内告诉我答案,否则你一块都别要。(自信)

深蓝:欺负人QAQ!!EMMMMMM……(蜜汁微笑)主人您的时间复杂度提醒我了。

Ration:哈?

深蓝:主人您在提醒我用莫队算法啊……

Ration:莫队?

深蓝:嗯。这是专门解决这种“可以离线处理(不用即及时处理)对于区间的询问”的问题的。

Ration:那么你就试试吧。

深蓝:嗯!你问吧!

Ration:10000之内,每500块钱为一段。

深蓝:好的。首先,我把10000这个数分成十段。然后把您的询问按照如下的排序规则进行排序:左端点在一个块里的,按照右端点的前后比较。不在一个块里的,就按照左端点来比较。同时,也记录每个询问的真实编号。然后,我开l,r两个int 变量,表示我正在决策的当前区间。接下来,不外乎四种情况:

1:当前区间右边界小于询问右边界

       右边界右移一位

       新获得的那个数的出现次数+1

       如果这个数的出现次数+1之后=1,也就是第一次出现的话,区间内种类数就+1

2:当前区间右边界大于询问右边界

       右边界对应的那个数的出现次数-1

       如果这个数的出现次数-1后=0,也就是第一次出现的话,区间内种类数就-1

       右边界左移一位

3:当前区间左边界小于询问左边界

       左边界左移一位

       新获得的那个数的出现次数+1

       如果这个数的出现次数+1之后=1,也就是第一次出现的话,区间内种类数就+1

4:当前区间左边界大于询问左边界

      左边界对应的那个数的出现次数-1

       如果这个数的出现次数-1后=0,也就是第一次出现的话,区间内种类数就-1

       左边界右移一位

重复这四个步骤,直到区间[l,r]和询问区间一样位置

那么这个询问的答案,就是此时的“区间内种类数”。

最后,在按照记录的询问的序号,把每个询问的“区间内种类数”排序,输出即可。

————————————————————————————————————

毕竟是计算机,算法口述完,深蓝就完成了编码,真的在(N*log(N*N)+N*sqrt(N)*log(N))内告诉了Ration答案

数了一遍,结果完全正确。

老板:一共105000积分点,感谢您的惠顾!

Ration:这得刷多少题才能回来啊啊啊!!!!!!!!(TAT)

深蓝:哈哈哈哈哈哈哈OVO~~~



原创粉丝点击