111qqz的小窝

老年咸鱼冲锋!

hdu 5213 lucky (莫队算法)

http://acm.hdu.edu.cn/showproblem.php?pid=5213
题意:n个数,m个查询,每个查询由4个数l1,r1,l2,r2构成,询问分别从[l1,r1]和[l2,r2]中各取一个数,和为给定的常数k的方案数。

思路:首先分别由两个区间取数不好搞,我们可以用容斥原理对区间变换。这是这道题最关键的一步。

官方题解:这道题需要一些莫队算法的知识 定义记号f(A,B)f(A,B)表示询问区间A,B时的答案 用记号+表示集合的并 利用莫队算法我们可以计算出任意f(A,A)f(A,A)的值 不妨假设A=[l1,r1],B=[l2,r2],C=[r1+1,l2-1]A=[l1,r1],B=[l2,r2],C=[r1+1,l21]容易知道(并没有很容易f(A,B)=f(A+B+C,A+B+C)+f(C,C)-f(A+C,A+C)-f(C+B,C+B)f(A,B)=f(A+B+C,A+B+C)+f(C,C)f(A+C,A+C)f(C+B,C+B) 因此一个询问被拆成四个可以用莫队算法做的询问 总的时间复杂度为O(msqrt(n))O(msqrt(n))

然后就是莫队算法的内容。值得一提的是,被拆成的四个子询问不必做四次莫队,可以合在一起,因为每一次询问对答案的贡献都不会受顺序影响,而且这样用时更短。

然后初始构造的时候用构造函数比赋值要方便许多。

还要记得多组数据记得清空各种数组。。。(因为忘记清空ans数组wa到死。。。)

最最关键的是,对于求两个数a+b==k这类问题(不一定是加,就是和两个数满足一个关系的时候),我们可以转换思维。a==k-b.也就是统计的时候是cnt[b]++,更新答案的时候,由于现在是b,我需要找有多少个a,也就是多少个k-b,所以是ans+=cnt[k-b];(要注意保证k-b>0)

 

 

说点什么

4 评论 在 "hdu 5213 lucky (莫队算法)"

提醒
排序:   最新 | 最旧 | 得票最多

路过,同为ACM爱好者。想问一下你用的是什么代码插件呢?

感觉貌似map会更好一点吗?

wpDiscuz