随笔分类 - 数据结构——线段树练习/树状数组/rmq
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=4747题意:我们定义mex(l,r)表示一个序列a[l]....a[r]中没有出现过得最小的非负整数, 然后我们给出一个长度为n的序列,求他所有的连续的子序列的mex(l,r)的和。思路:首先因为n的最大值就是2*10^5 所有我们字需要考虑200000之内的数就好了,然后O(2*n)可以求出(1,1),(1,2), (1,3),(1,4) ... (1,n)来 mex是不减的。然后我们考虑将第一个数拿走我们就能够得到(2,2),(2,3) ......(2,n) , 如何求他们?下边给出图解:下边是粘贴别人
阅读全文
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=3874题意:给你n个数,然后给出m个的询问[l,r]问[l,r]中不同的数的和为多少?思路:单纯只考虑不同数的和的话,可能该数在之前出现过,后边又出现了,但是所求的区间不包括前边那个数,那么这个数就要被加进来。关键是如何维护该区间不包含重复计算同一个数。首先我们离线处理所有询问,然后按r排序,然后遍历一边处理那些还没被加进线段树的数,如果他之前出现过了,那么就将之前的删除,然后再吧后边的加进来,这样既能保证同一个数只被计算的一次了,而且不影响后边的询问。这里关键是按r排序之后的处理:#include <
阅读全文
摘要:http://codeforces.com/problemset/problem/159/C题意:给你一个字符串s,给出一个数k,k倍的s串组成新串str。然后给出n个操作,每个操作对应着pi,ci意思是将第pi个字符ci从str中删除,求最后得到的字符串。思路:首先我想到的是利用vector里面的erase快速的删除,开一个vc[26]来存取每个字符然后模拟删除过程,才开始自己一维erase的时间复杂度为O(1)如果这样肯定不会超时,结果事与愿违果真TLE了。问了问别人晚会上搜了搜原来erase函数的平均复杂度竟然是O(n)这样固然超时,可是看了看AC的代码里面也有用vector + era
阅读全文
摘要:http://codeforces.com/problemset/problem/91/B题意:给你n个数,求得i 到n中小于a[i]的最右边的a[j],然后求a[i]到a[j]之间包含了多少个数。思路:首先自己在做这道题的时候没有认真读题,直接把题意搞成求得i 到n中小于a[i]的最右边的a[j],然后求a[i]到a[j]之间包含了多少个小于a[i]的数了。。。结果样例都没过。唉自己还是太粗心,一定要认真把题意搞清楚,然后把想法想好了再敲。不过也算是做了另一道题目吧。首先我的思路,好像比较复杂。 我们利用线段树维护小于a[i]的区间[1,a[i]]的最大坐标值,当然要将数列离散话,因为a[i
阅读全文
摘要:PKU 1151 && hdu1542 Atlantis 矩形面积并http://poj.org/problem?id=1151题意:给出n个矩形,每个矩形给出左下角坐标,右上角坐标。然后求矩形并的总面积;思路:浮点数先要离散化;然后把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用cnt表示该区间下边比上边多几个,sum代表该区间内被覆盖的线段的长度总和这里线段树的一个结点并非是线段的一个端点,而是该端点和下一个端点间的线段,所以题目中r+1,r-1的地方可以自己好好的琢磨一下;这里点到线段的转化不好理解:我们的线段树的叶子节点表示的是线段,座椅如果我们求1到
阅读全文
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=4288题意:给出三种操作add x 向集合里添加x(这里保证集合中不存在该元素), del x删除集合里的x(这里保证集合里面不存在x),sum:然后给出N个操作,输出每次的sum;思路:才开始看到这题就想到了上次那个维护区间(i-a)%k == 0的题目区间部分更新的题目,每个线段树上的节点添加记录该区间内模k余(0到k-1)的值,可是这里是求整个区间,而且一旦删除一个值它们原来满足模k的余数就会发生改变。直接就晕了。。。看了下解题报告原来和上次的题目是类似的,我们还是记录当前区间模5余(0到4)的值,只是
阅读全文
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=4267题意:给你N个数,有两种操作:2 x询问a[x]的值;1 a b k c a <= i <= b 满足(i - a)%k == 0的a[i] += c;(1 <= N <= 50000) (1 <= a <= b <= N, 1 <= k <= 10, -1,000 <= c <= 1,000)思路:一看就知道这肯定是线段树的题目,可是区间内满足(i - a)%k == 0的点才进行处理怎么办,如果i i + k,i + 2k的循环处理的
阅读全文
摘要:pku 3264http://poj.org/problem?id=3264题意:给定n个奶牛的高度,求区间[s,e]中最高与最低高度的差值。rmq模板题目:求出最高最低然后求差。注意这里f[i][j]表示从j开始的2^i次方个数的最值。View Code #include <cstdio>#include <cstring>#include <iostream>#include <cmath>#define maxn 50007#define N 22using namespace std;int fMin[N][maxn],fMax[N][m
阅读全文
摘要:pku 3321Apple Treehttp://poj.org/problem?id=3321题意:苹果树上有n个分叉,每个插上长着一个苹果,给出每个叉的关系,然后给出两种操作1:C x改变分叉x的苹果(如果有就拿走,如果没有就长出一个) Q x询问包括树叉x在内以及其子树的苹果数量;思路:才开始就在如何将树结构转化成线性数组结构然后用树状数组求解上难住了,最后看了一下解题报告,原来是首先边表(或邻接表)存树,然后dfs对每个节点重新编号每个节点对应着s,e两个编号。s是首先进入该点时的编号也即它本身的新标号(对应了线性数组的编号),e是搜索完子树后返回根节点的编号也即根节点本身所包含的子树
阅读全文
摘要:这类题目会询问区间中满足条件的连续最长区间,所以PushUp的时候需要对左右儿子的区间进行合并(这里最难理解)hdu 3308http://acm.hdu.edu.cn/showproblem.php?pid=3308题意:给定n个数,下标从0-n-1,给出两种操作Q x,y询问区间[x,y]中的最长上升子序列(LCIS), U x,y 将下表为x的值替换成y(单点更新)。输出每次询问的值。思路:U操作的单点更新就不必多说了,这里关键理解的是区间的合并;节点信息:struct node{ int l,r;//记录该节点的左右边界 int lm,rm,sm;//分别对应该点包括最左点...
阅读全文
摘要:这一块关键理解延迟标记(或者说懒惰标记)lz[],就是每次更新的时候不要更新到底,用延迟标记使得更新延迟到下次需要更新或者询问到的时候再更新。这里主要包括两个方面:1:成端替换; 2:成端累加(累减);hdu 1698http://acm.hdu.edu.cn/showproblem.php?pid=1698题意:给定n个连续的奖牌(每个奖牌都有一个价值),初始都为铜牌。有q个操作X,Y,Z,将区间[x,y]内的奖牌的价值改为Z,问经过q个操作后总的价值为多少。思路:就是典型的成段替换,lz标记,关键是注意将lz pushdown。。View Code #include<iostream
阅读全文
摘要:hdu1166http://acm.hdu.edu.cn/showproblem.php?pid=1166题意:中文不说了,大体意思是给定n个数;接下来每行有一条命令,命令有4种形式:(1) Add i j,i和j为正整数,表示第i个营地增加j个人(j不超过30)(2)Sub i j ,i和j为正整数,表示第i个营地减少j个人(j不超过30);(3)Query i j ,i和j为正整数,i<=j,表示询问第i到第j个营地的总人数;(4)End 表示结束,这条命令在每组数据最后出现;很纯的单点更新题目:View Code #include <cstdio>#include &l
阅读全文
摘要:HDU 4217 Data Structure?http://acm.hdu.edu.cn/showproblem.php?pid=4217CZ做的一道题目,我帮忙看了看。题意:给定N个数(1---N),K个操作,然后给K数,i1,i2,i3.......ik 每次取走当前状态下等的第i个数(从小到大的),问取走的数的和。给的那个的n为262144可以断定肯定是O(n*log(n))级的算法,所以选定线段树。叶子节点赋值为1,这些节点存储的就是数的个数,在添加一个val数组记录是哪个数。每次更新将节点a[rt]变成0,找出对应的val[rt]即可。这里坑爹的地方时sum求和时,要用—int64
阅读全文