POJ4638

来源:互联网 发布:旅馆住宿登记软件 编辑:程序博客网 时间:2024/06/08 13:30

题意:给定n个数的序列,进行m次查询,求查询区间里的连续数段的个数

例:(1,3,5,4,2)查询区间[2,4]的连续序列个数为1

 

题解:利用树状数组来维护区间,其sum()函数求的值为从1位置到pos[v[i]]位置的连续序列的段数,每一个数组元素的值是表示v[i]这个数插入进树后对总的连续序列的个数的影响。在将位置为pos[v[i]]的数插入到树中时,和前面插入的数进行判断,如果前面已经插入了v[i]-1和v[i]+1这两个数,那么再插入这个数的同时,之前的两段连续数列就变成了一段,所以需要对个数进行减1,即操作add(pos[v[i]],-1),同理如果前面只有v[i]-1或v[i]+1中的一个数,那么个数是没有变化的,如果前面没有v[i]-1和v[i]+1这两个数,那么个数加1。

 

先对查询区间作离线处理,再将其按照左端点的值进行从小到大的排序。

 

从前向后逐个删除v[i], 因为在前面的数值要么是在已经存在的区间中,要么开创一个新的区间,不可能存在一个区间是由位置靠后的数值开创的现象。删除前面的数值v[i]时,add(pos(v[i]-1),1),add(pos(v[i]+1),1).