模拟
enum.exe/enum.in/enum.out
题意描述:
有一列整数,共n个。每次可以对这些整数操作,有两种操作:
1 第i个到第j个整数分别加上数p
2 询问这些数中比t小的数的个数。
输入文件(enum.in):
第一行有两个数,n和m(1<=n<=100000,m<=10,000),表示数的个数和操作数。
第二行n个整数,表示每个数的初始值。
以后m行,每行开始一个数q。
若q为1,则后面跟三个数i,j (i<=j),表示两个下标; p(-1000=p<=1000),表示修改的数。
若q为2,则为询问操作,后面跟一个数t。
输出文件(enum.out):
对每个询问操作输出数列中比t小的个数。
输入样例:
5 3
1 2 3 4 5
2 0
1 1 5 -10
2 0
输出样例:
0
5
//前几天一直很衰,根据rp守恒定律,今天终于爆发了!
这个题目的变态之处是:操作2适合平衡树,操作1适合线段树,加起来之后?线段树套平衡树?
也许可以,但一定很丑!
曾经在学线段树的时候,看到过块状链表,那时候觉得很慢,而对于这道题,就不得不选它了.......
将1~ n 分为 若干个长度为trunc(sqrt(n))的“块”,然后利用线段树的lazy思想,对于修改操作,先用一个lazy数组记录,等到
查询时在统一做处理。
但这道题即使这样,一次查询仍然是O(n),于是可以考虑修改过程中维护每一段递增(快排就行了),查询时就可以对每一段进行二分了。
于是,这道题的一次修改和查询都是O(sqrt(n)*log(sqrt(n)));(真难写)
只要常数弄得好就可以过了@