数据结构-线段树
文章平均质量分 53
KIJamesQi
这个作者很懒,什么都没留下…
展开
-
hdu1166(线段树单点更新区间查询)
/*****************************************Author :Crazy_AC(JamesQi)Time :2015File Name :*****************************************/// #pragma comment(linker, "/STACK:1024000000,10240原创 2015-09-30 14:29:30 · 276 阅读 · 0 评论 -
poj2528(离散化 + 染色)
若第i次在区间[ai , bi]染色,则把[ai , bi]的每一格都染色为i。后染的颜色覆盖先染的颜色。由于染色N次,定义一个标记数组tagcol,从数轴第一格开始检查,一直检查到最后,出现过得颜色则记录到tagcol,最后统计tagcol中不同颜色的个数,就是所求。 数据规模太大,必定TLE。 应该用线段树去求解,这题只是线段树的入门水题,不懂线段树的同学去原创 2015-09-30 22:25:54 · 432 阅读 · 0 评论 -
hdu3974Assign the task(简单树hash,线段树区间更新,单点查询)
题目大意:给定一个上下级关系树,一开始都是没有做事的,然后给定x,y,就是指定x及其下属此时全部做事件y。最后就是查询x此时在做那件事情。思路:把子树上的点连续的hash到线段树上去,用线段树更新,hash的时候采用dfs后序遍历。/*****************************************Author :Crazy_AC(JamesQi)Time原创 2016-04-22 16:22:12 · 393 阅读 · 0 评论 -
lightoj1101 ASecret Mission
题意给你张图,n个点m条双向边,有正边权。然后是Q个询问<u,v>,表示u到v的路径上的最大值的最小。分析求一个MST是显然的,按照最小边权的贪心把图连通。然后就是普通的树链剖分。/*****************************************Author :Crazy_AC(JamesQi)Time :2016File Name :***原创 2016-07-25 15:14:14 · 382 阅读 · 0 评论 -
Lightoj1083 Histogram(线断树+二分)
选定a[i]是,以它的高为准,往左找第一个小于它的后一个位置,往右找第一个小于它的前一个位置。const int maxn = 3e4 + 123;int a[maxn];int n;struct SegmentTree { struct node { int l, r, _min; }p[maxn<<2]; void build(int rt,int原创 2016-08-05 13:41:59 · 405 阅读 · 0 评论 -
Lightoj 1411 - Rip Van Winkle`s Code(线断树)
题意就是用快速的方式实现在面的四种操作。long long data[250001];void A( int st, int nd ) { for( int i = st; i <= nd; i++ ) data[i] = data[i] + (i - st + 1);}void B( int st, int nd ) { for( int i = st; i <= nd;原创 2016-08-03 10:11:11 · 464 阅读 · 0 评论 -
poj2104 K-th Number(静态区间k大,主席树)
主席树 给出一个有n个元素的数列,每次问区间[a, b]间第c小的数是哪个。#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>using namespace std;#define Rep(i, l, r) for (int i = l;i <= r;++i)#define Rrep(原创 2016-08-20 17:14:20 · 409 阅读 · 0 评论 -
spoj DQUERY - D-query(区间不同数的个数 主席树 or BIT)
题目链接 给出含有n个数字的序列,每次问区间[l,r]不同数的个数。 可以用主席树也可以用树状数组,做法都是同一个原理。从左往右扫一遍,记录每个数上一次出现的位置。当扫到i位置时, 把a[i]上一次出现的位置-1,i这个位置+1。然后对于所有询问区间[x, i]进行回答(BIT区间求和)。主席树也是这个原理, 只是要保存历史版本。const int maxn = 3e4 +原创 2016-08-21 12:20:49 · 917 阅读 · 0 评论 -
SPOJ COT(树上k大,主席树+LCA)
给出一颗含有n个节点的树,每个节点有个权值。问u到v的路径上第k小的权值是多大。 做法就是主席树+LCA,每个节点建立一颗从根(默认为1)到它的线断树,那么u->v路径的线断树就等于T[u] + T[v] - 2*LCA(u, v) + (l <= a[LCA] && a[LCA] <= r)。/*****************************************Author原创 2016-08-23 20:45:12 · 557 阅读 · 0 评论 -
HDU 4729 An Easy Problem for Elfness(树上主席树+LCA+二分)
题目大意:给你一棵树,每条边有一个容量。然后m个询问,每个询问是互相独立的,给你两个点S, T,一个预算K, 建一条容量为1的新边的费用A(可以建在任一两个节点之间,包括S,T),将某一条现有的边容量扩大1的费用B。 问从S到T在预算允许的情况下最大流是多少。 这个分两种情况来讨论最优解: 1.如果A≤BA \leq B,显然新建不会比扩展差,可以建立kA\frac{k}{A原创 2016-08-23 21:14:44 · 445 阅读 · 0 评论 -
CodeForces 474E Pillars(线断树区间最大)
题目链接 给出n个数字,和最小间隔d。从i能走到j的充要条件就是|ai−aj|≥d\vert a_i - a_j \vert \ge d ,求最长的路径长度并输出路径,有多解输出任意一组路径。 思路就是dp[i]表示以i结尾的最长路径长度,dp[i]<-{pre{dp[j]}里面满足条件且最长的长度} + 1, 这里查找的就可以是区间最大值的查找,因为要记录路径,所以里面还需要最大值原创 2016-09-19 19:59:56 · 568 阅读 · 0 评论 -
HYSBZ - 1036 树的统计
思路:这是经典的树链剖分,有三个操作。1.两点路径中的最大点权;2.两点路径中的点权和;3.更改某个点的权值;如果不用数据结构维护的话,直接搜带来的就是时间消耗太大,主要是因为搜的过程中做了很多无用功,不够直接的找到目标点和线段。树剖就是先按照儿子节点数的节点多少进行划分险段,线段不会相交,树上两个点的路径必然是通过它们的LCA的。我们可以通过线段往上找,知道两个点在同一个线段中,原创 2015-12-12 16:34:43 · 322 阅读 · 0 评论 -
uva11992 Fast Matrix Operations
思路:看似一个二维矩阵值的更新,其实就是换成多条线段更新,线段树。总共有3种操作:1. 1 x1 y1 x2 y3 val(在满足(x,y)的点上+val)2. 2 x1 y1 x2 y2 val(把满足条件的点清空为val)3. 3 x1 y1 x2 y3 查询区间值 sum min max。因为有延迟标记,所以每次要down和up下,二维在down的时候还要先考虑区间是否被原创 2015-11-04 17:10:15 · 420 阅读 · 0 评论 -
SPOJ QTREE Query on a tree
思路:树链剖分的一种,将边权赋值给这条边的儿子节点,(u,v)也就是v节点,u->v,然后线段树维护节点之间的关系。注意的是,如果u,v在同一天链中的话且dep[u] // #pragma comment(linker, "/STACK:1024000000,1024000000")#include #include #include #include #include #in原创 2015-12-13 20:28:16 · 347 阅读 · 0 评论 -
hdu1394(单点更新)
思路:可以先求开始序列的逆序数,一开始记录每个叶子节点的值为0,然后对于每个数,插入之后更新一下,对于当前的x[i],需要插叙[x[i], n - 1]之间的数已经出现了多少个。求出一开始的逆序数之后,就可以通过递推关系式以此找出后面的逆序数对。/*****************************************Author :Crazy_AC(JamesQi)T原创 2015-09-30 14:31:29 · 314 阅读 · 0 评论 -
poj2481(单点更新)
思路:排序 + 线段树;题目说的是[si,ei],[sj,ej],要的是前者包含后者,前者强。然后问的是对于给定的区间有几个比她强(前面的定义)的区间。我们可以先让s满足包含的条件,再来考虑e的问题,现在要先排个序,s小的排前面,s相同时e大的排前面。先把第一个区间插入进去,对于后面的如果和前一个区间完全相同,就HH[p[i].id] = HH[p[i - 1].id],如果不一样,就Qu原创 2015-09-30 15:53:05 · 433 阅读 · 0 评论 -
poj2759(单点更新)
思路:题目说的是有一个h*w的空板子,然后在上面要粘贴1*w的广告。广告之间是不能重叠的,然后就是如果没有这个广告的位置了,就输出-1,有的话就输出贴在第几行。然后就是线段树维护[L,R]之间的最大宽度,初始宽度w。如果这一行贴了广告的len[L] -= w[i]。这样分析下来就是线段树的单点更新了QWQ。/***********************************原创 2015-09-30 15:49:32 · 517 阅读 · 0 评论 -
poj2182(单点更新)
len[rt]表示当前树中有多少个空位;还有就是在网右子树走的时候一定要减掉左子树的空位数目。/*****************************************Author :Crazy_AC(JamesQi)Time :2015File Name :*****************************************///原创 2015-09-30 16:18:14 · 487 阅读 · 0 评论 -
hdu1698
思路:col数组要来标记当前区间的值,一开始所有的区间都为0,然后我们更新的时候,如果当前的区间的col不为0,则说明该区间是纯的,此时,我们应该把这个区间的col往左右子树传,同时计算sum的值,由于是纯的,因此当前节点的左子树和当前节点的右子树的sum可以直接求得,然后在把当前的col改为0,表示当前节点覆盖的区间不纯。(题目懂了就好了)QAQ/**********************原创 2015-09-30 20:21:34 · 399 阅读 · 0 评论 -
poj3468(区间更新->记录增量)
思路:题意就是一个区间和的查询与区间增减(减a等同于增加-a);更新的时候只更新到段,等到下次更新或者查询的时候,碰到已经被标记过的,往下顺延就行。一开始int与long long 进行计算时没有转类型,然后就是。。。。原创 2015-09-30 19:34:56 · 386 阅读 · 0 评论 -
lightoj1135(线段树 + 延迟标记)
思路:题目就是0 ~ n - 1个数,m次操作,往区间添加1或者查询区间有多少个可以被3整除的数;被三整除的余数就是0,1,2。如果添加1就变换三个数的值;点击题目链接/*****************************************Author :Crazy_AC(JamesQi)Time :2015File Name :**原创 2015-10-03 16:49:26 · 293 阅读 · 0 评论 -
uva11235 Frequent values
思路:这个是RMQ变形,因为这个是一个non-decreasing order序列,所以同一个数是连续的,那么我们可以先处理下每个连续的数的左右边界,也就是l[i],r[i]的值,num[i]表示当前位置的数所属段的标号。对每种数进行编号,也就是每个段。建立Segment-Tree,再就是询问的时候,因为给的是原坐标,所以要转换成所属的段标号,如果是同一个段,那么直接坐标相减+1,否则就进行RMQ原创 2015-11-06 16:52:01 · 524 阅读 · 0 评论 -
uva12299(RMQ with Shifts)
思路:这题一眼就是线段树单点更新,,,训练开着题的时候就是傻逼了,,,一看数据很大,时间很小,TLE定了,,,3个小时后再来看,发现别人过的时间都只有300-ms,,,然后再读题的时候就看见了 // #pragma comment(linker, "/STACK:1024000000,1024000000")#include #include #include #include #i原创 2015-11-02 22:36:04 · 385 阅读 · 0 评论 -
lightoj1085 All Possible Increasing Subsequences
思路:这题就是求这个序列中有多少个上升序列,如果按照一般的思路去for...for...for...的话,必然是超时的,所以这时候就需要减少时间上的复杂度,首先,dp[i] = ∑dp[k] (a[i] > a[k] && i > k),这样我们在往后面扫的时候需要快速的求出前面的和也就是等式右边的部分,这个当然就是线段树去完成了,由于单个数很大,只能离散化,还好n不大,离散化下来的话也就是n个数原创 2015-12-12 17:26:17 · 408 阅读 · 0 评论 -
hdu5919 Sequence II(主席树求区间数种数和k大查找)
题目链接 给你一个含有n个数的数列,m次查询。每次查询给出l和r两个数,表示子序列a[l]…a[r],然后子序列中有k种数(需要自己求出k值), p[j]表示第j种数从左到右第一次出现的位置,那么会得到p[1]…p[k] && p[1] < p[2] < … < p[k]。然后倒着建立主席树,然后就类似区间k小的查找。#include <stdio.h>#define min(x, y原创 2016-10-04 23:16:15 · 549 阅读 · 0 评论