摘要:此题陷阱多多:数据类型(相应的输入输出)、区间端点可能反序、如果用C提交注意强制转换的格式(int(x)是不对的);思路:每次如果开根号的区间内含有未达到0或1的数就一直向下,找到这些数并直接更新一次,这样最多跟新4*N次,加上线段树的复杂度,为4*N*lgN,是最坏情况的复杂度,可能由于开根号耗时较多,总体比较耗时(700ms+),查询的复杂度为lgN。# include <stdio.h># include <math.h># define N 100005# define ls ((r)<<1)# define rs ((r)<<1|1)#
阅读全文
摘要:维护某个位置 i 左右可以到达的最大长度lx, ly,那么询问的输出为lx+ly-1(当然,如果 i 已经被标记(炸毁且尚未修复)输出0,这种情况加个判断);容易发现: 每次删除一个点时,这个点左边可以到达的所有点可以向右到达的最大长度要减去 ly,同理这个点右边的点可以到达左边的最大长度要减去 lx; 当修复一个点时,可以先询问它左(右)边的那个点的最大连通长度 lx(ly),那么可以对它前面 lx 个点向右可以到达的长度加上 ly+1,同理对它后面 ly 个点向左可以到达的最大长度加上 lx+1(两种操作都包含当前这个点),这样就相当于完成了修复;由于每次修复的是最近一次删除的点,可以..
阅读全文
摘要:难在异或对询问区间最大连续1长度的影响,每次异或时,把异或标记更新到底(cover标记不为-1),直接更新当前最大连续1区间的长度。 1 # include <stdio.h> 2 3 # define N 100005 4 5 # define ls ((r)<<1) 6 # define rs ((r)<<1|1) 7 # define mid (((x)+(y))>>1) 8 9 int n, m, a[N]; 10 int cover[N<<2]; 11 int sum[N<<2], lcon[N<<2
阅读全文
摘要:维护左、右、总的连续区间长度,在 update 求总的最大长度时,写成了tsum[r] = Max(rsum[ls]+lsum[rs], Max(lsum[r], rsum[r])); 所以一直出错。/*notepad++ 调用 g++ 编译cmd /k C:\ACMSOFT\DEVC\Bin\g++.exe -g -W -Wall -o $(CURRENT_DIRECTION)\$(NAME_PART).exe $(FULL_CURRENT_PATH)*/# include <stdio.h># define ls ((r)<<1)# define rs ((r)&l
阅读全文
摘要:线段树经典入门题目;这道题有几点不同的地方:1. 维护的是集合,一个点或者一段区间都是一个集合,(2,3) 是一个集合,不能简单的用线段代替集合;2. 用离散的 01 值表示集合,对集合的运算需要转化为 01 区间的异或与赋值操作;3. 01 区间上进行异或和赋值,在 pushdown 的时候只能存在一个信息,一个线段要么被赋值,要么异或,不能既被赋值,同时进行异或(cover[]和xor[]不能同时有效);4. 结果要求输出运算结果(集合),在查询时,要做的不是查询到左端点、右端点,而是把被赋值的区间全部标记下来(O(n)),然后一次扫描完成输出,这道题卡了很长时间就是这里没想清楚(既然用了
阅读全文
摘要:从后往前逐个添加,每次放到第pos[i]+1个空位置上;维护区间内空位置的个数,修改和查询都是二分查找。 1 # include <stdio.h> 2 3 # define ls ((r)<<1) 4 # define rs ((r)<<1|1) 5 # define mid (((x)+(y))>>1) 6 7 # define MAXN 200010 8 9 int p[MAXN], v[MAXN], a[MAXN];10 int sum[4 * MAXN];11 12 void build(int x, int y, int r)13 {
阅读全文
摘要:区间修改,询问,带有 lazy tag。# include <stdio.h># define ls ((r) << 1)# define rs ((r) << 1 | 1)# define mid (((x)+(y))>>1)# define MAXN 100005typedef long long int LL;int a[MAXN];LL sum[MAXN * 4];LL lazy[MAXN * 4];void update(int r){ sum[r] = sum[ls] + sum[rs];}void build(int x, int
阅读全文
摘要:带 lazy tag 的线段树,维护区间和,含区间修改操作(最后一次询问)。# include <stdio.h># define MAXN (100005 * 4)char lazy[MAXN];int sum[MAXN];void build(int x, int y, int r){ sum[r] = y-x+1; lazy[r] = 0; if (x == y) return ; int mid = (x+y)>>1, ls = r<<1, rs = r<<1|1; build(x, mid, ls); build(mid+1, y, r
阅读全文
摘要:第三次写这个题了,这次不再用线段树,因为估计了暴力能过(复杂度的估计不太明显,最坏不超过10^8,实际很可能更低或者大部分情况下更低(O(n)))!235ms,超时了几次,猜测是因为memset,所以加了个位优化,AC。 1 # include <stdio.h> 2 # include <stdlib.h> 3 # include <string.h> 4 5 # define id(x) ((x)>>3) 6 # define of(x) ((x)&0x7) 7 # define get(x) ((h[id(x)]>>of
阅读全文
摘要:看了notonlysuccess的博客线段树维护最大值,这道题需要注意的是当h>n时,令h = n,原因是如果wi都小于w,最多只用前n行,反之一定结果是-1。# include <cstdio>int h, w, n, wi;int m[4 * 200010];int Max(int x, int y){ return x > y ? x : y;}void update(int r){ m[r] = Max(m[r << 1], m[r << 1 | 1]);}void build(int x, int y, int r){ m[r] = w
阅读全文
摘要:包含插入和询问的线段树,简化版,据说这道题暴力也能过。Description现在请求你维护一个数列,要求提供以下两种操作: 1、 查询操作。 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。 限制:L不超过当前数列的长度。 2、 插入操作。 语法:A n 功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。 限制:n是非负整数并且在长整范围内。 注意:初始时数列是空的,没有一个数。Input第一行两个整数,M和D,其中M表示操作的个数(M <= 200,000),
阅读全文
摘要:线段树,离散化;WA了三次,前两次主要是查询时只要遇到标记了颜色就要返回,而不是标记颜色并且没记录过就返回,后一次是空间开的小,因为离散化可能使数据量增加一倍,因此空间至少要开到区间数目的 4 倍;-----------------------------------------------------------2012/4/15View Code # include <cstdio># include <cstring># include <algorithm>using namespace std;# define N 10000 + 5int n,
阅读全文
摘要:线段树,维护区间的和,支持区间范围修改,注意由于增加的标记传递时是累加起来,结果会超出 int ,要用 long long;--------------------------------------------------------------DescriptionYou have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given int
阅读全文
摘要:------------------------------------------------------------------------------------线段树的区间操作:修改区间内的值,反转区间内的值,区间查询;------------------------------------------------------------------------------------Description维护一个只有0和1的整数序列,支持以下操作:1 x y v : 将区间[x,y]之间的所有整数都变为v(v为0或1);2 x y : 将区间[x,y]之间所有的1变为0,所有的0变为
阅读全文
摘要:线段树,维护的是区间内整数的个数,每次插入 x 时,查询在 x 的前面比小的数的个数,并计算出比 x 大的数的个数 cnt[x] ,最后将 cnt 累加,即为逆序数;将队首的数放到队尾后逆序数改变:n-1-a[i], a[i] 为原始序列中第 i 个数的值;----------------------------------------------------------------------2012/7/15之前的代码中,cnt[i] 是记录比第 i 个数大的的在它前面出现的数的个数,第二次写发现不需要。# include <cstdio># include <cstri
阅读全文
摘要:因为输入是按y坐标升序的,对每个点统计在它左边的个数就是它的level(线段树);DescriptionAstronomers often examine star maps where stars are represented by points on a plane and each star has Cartesian coordinates. Let the level of a star be an amount of the stars that are not higher and not to the right of the given star. Astronomers
阅读全文
摘要:这道题来自于 The 36th ACM/ICPC Asia Regional Dalian Site —— Online Contest 线段树求第 k 大值,包含修改和询问;----------------------------------------------------------------------------Problem DescriptionXiao Ming and Xiao Bao are playing a simple Numbers game. In a round Xiao Ming can choose to write ...
阅读全文
摘要:线段树的做法,1438MS;------------------------------------------------------------------DescriptionFor the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer John decides to organize a game of Ultimate Frisbee with some of the cows. To keep things simpl
阅读全文
摘要:线段树,修改,维护区间最大最小、和;Description维护一个整数序列,支持以下操作:1 x v : 将第x个整数的值修改为v;2 x y : 查询区间[x,y]之间的最小值;3 x y : 查询区间[x,y]之间的最大值;4 x y : 查询区间[x,y]内的整数和。Input输入文件包含多组测试数据。对于每组测试数据,第一行为一个整数N(1<=N<=10^5),表示,接下来一行有N个整数,再接下来一行有一个整数M(1<=M<=10^5),表示一共有M个操作。数据保证对于查询操作结果均在int的表示范围内。Output对于每个查询均用一行输出查询的结果。Sampl
阅读全文