您的位置:首页 > 其它

BZOJ-1878-HH的项链-SDOI2009

2015-04-02 23:15 253 查看
描述

有n个位置(n ≤ 50000), 每个位置有一个颜色(颜色数 ≤ 200000).

询问[L, R]区间的颜色种数.

分析

两种解法都做了一下

1. 离线树状数组统计
HZWER:
将所有询问按照左端点进行排序, 将所有颜色的第一个点x, 将a[x]++, 然后从左往右扫, 扫到一个点x,
将a[next[x]]++, 碰到一个询问l,r输出sum[r]-sum[l-1], 其中sum是a数组的前缀和, 求前缀和可以用树状数组.
之所以这样做关键就是避免同种颜色计算多次, 这也是用树状数组解决问题的关键. 在L前的一个位置x, 如果next[x]在L之前, 用树状数组统计query(R)-query(L-1)时被减掉没有计算进去, 但之后一定会在结束对[L, R]的统计之前遇到这个next[x]; 如果next[x]在[L, R]的区间中, 那么更新next[x]之后query(R)-query(L-1)比原来大1,
也就是这个颜色被统计进去了, 而因为next[x]>L, 所以不会再遇到这个next[x]; 如果next[x]>R, 那么不会影响结果.
好巧妙的方式
O(nlogn)

2. 莫队算法
分块的做法:
将询问分 √n 块, 每一块内按R从小到大排序, 不同块之间按L从小到大排序. 然后用两个指针{p, q}扫描, 统计[p, q]区间内每个颜色的出现次数, 同时根据当前的答案统计对[L, R]区间的颜色种数造成的影响, 直到p==L&&q==R, 当前的答案就是[L, R]区间的答案.
感性的理解是这样分块让指针p, q在统计某一询问移动的次数尽可能少. 至于为什么我觉得没必要证啦...
O(n√n)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: