线段树

越野赛车问题——线段树分治+并查集

戏子无情 提交于 2019-12-17 19:53:05
题目 【题目描述】 小 $H$ 是一位优秀的越野赛车女选手。现在她准备在 $A$ 山上进行赛车训练。 $A$ 山上一共有 $n$ 个广场,编号依次为 $1$ 到 $n$ ,这些广场之间通过 $n-1$条双 向车道直接或间接地连接在一起。对于每条车道$i$ ,可以用四个正整数 $u_i,v_i,l_i,r_i$描 述,表示车道连接广场 $u_i$ 和 $v_i$ ,其速度承受区间为$[l_i,r_i]$,即汽车必须以不小于 $l_i$ 且不大于 $r_i$ 的速度经过车道$i$ 。 小 $H$ 计划进行 $m$ 次训练,每次她需要选择 $A$ 山上的一条简单路径,然后在 这条路径上行驶。但小 $H$ 不喜欢改变速度,所以每次训练时的车速都是固定的。 现在小 $H$ 告诉你她在$m$ 次训练中计划使用的车速,请帮助她对于每次训练,找 到一条合法的路径(车速在所有车道的速度承受区间的交集内),使得路径上经 过的车道数最大。 【输入格式】 输入文件的第一行包含两个正整数 $n,m$ ,表示广场数和训练次数。 接下来 $n-1$ 行,每行四个正整数 $u_i,v_i,l_i,r_i(\leq n)$,描述所有车道。 最后 $m$ 行,每行一个正整数 $v(\leq n)$ ,表示小 $H$ 每次训练时使用的车速。 【输出格式】 输出 $m$ 行

可持久化数据结构题目泛做。

我只是一个虾纸丫 提交于 2019-12-17 18:15:18
个人理解: 每个新的线段树的一个结点保存的是1...位置 i中的数字在相应的区间上有几个。 然后我们用r-(l-1)得到的就是l...r上的中字在相应的区间中出现了几个。 题目1 POJ2104 题目大意:静态查询区间第K小值。 裸的可持久化线段树。 1 #include <cstdlib> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstdio> 5 #include <cstring> 6 7 using namespace std; 8 const int N = 100000 + 5; 9 10 struct SegTree { 11 int l, r, size; 12 }Node[N * 30]; 13 14 struct data { 15 int v, pos; 16 bool operator < (const data &k) const { 17 return v < k.v; 18 } 19 }a[N]; 20 21 int n, m, rank[N], l, r, k, root[N], tot; 22 23 void build(int &o, int l, int r) { 24 o = ++ tot; 25 Node[o].l = Node[o].r = Node[o].size

浅谈算法——线段树

情到浓时终转凉″ 提交于 2019-12-17 05:25:41
前言 线段树作为高级数据结构,可以做非常非常多的事情,那么线段树到底是什么呢,我们就此了解下 一.基本概念 线段树并非什么特别高级的东西,顾名思义,它也就是一棵树。那么为什么叫线段树呢?因为树的节点上存的就是一些区间,也就是线段。那么它长啥样呢? 嗯,如上图,就是一个区间[1,9]的线段树。有些节点是叶子节点,叶子节点长度为1,不能继续往下分。叶子节点记录的信息是最基本的信息,而其他非叶子节点记录的就是两个儿子信息的合并(合并的方法有很多,具体情况具体分析)。线段树的左右区间分别为 \([l,mid],(mid,r]\) 。而且,由于线段树是一颗二叉树,并且线段树是二分构造,所以它非常平衡,深度也是 \(log n\) 级别的 怎么记录?记录的话,可以学习堆的建造方法,当前点是 \(p\) ,左儿子即是 \(p*2\) ,右儿子就是 \(p*2+1\) 二.操作 线段树被发明出来,肯定有它的道理,线段树由于能快速的支持一些操作,因此被广泛使用 1.单点修改 高级数据结构必然要能修改值,修改的话,只需要从线段树的根开始,一路查询到叶子节点,更新完叶子节点后,再将叶子节点到根的路径上的点一路更新一下即可。时间复杂度最大是线段树的深度,即 \(O(log n)\) void change(){//丑陋的伪代码,x是我要修改的点的位置 if (到达叶子节点) 修改当前节点; return;

【説明する】线段树

孤街浪徒 提交于 2019-12-17 03:12:40
前言 终于是学完了线段树!根据多为dalao的博客以及 悉心 教导,终于掌握了一些基本的应用~ 但是问题是:刚刚接触的朋友们甚至都不明白什么是线段树,所以更加不会写代码咯( 蠢问题! ) 所以先来扯一下线段树是一个什么样的东西呗: 如果实在看不懂的话,可以直接去 ① dalao博客 ② 学姐博客! (Ps:这是两种不同方法哦,讲真会一种比较不错了哈~) 不容置疑,线段树是一种数据结构,数据结构在我看来就是优化的一种方式咯. 引例: 给出n个数,n<= 一个数, 和m个询问,每次询问区间[l,r]的和,并输出. 一般思路,先暴力。就挨个枚举呗。可是当 这个数 很大的时候呢,就容易超时.这时我们就需要想一个数据结构来优化我们的算法咯. 所以就出现了线段树这个 鬼东西 . 一.概念: 什么是线段树呢?通俗易懂!!! 不就是说在一棵树上存着线段咯 .(大概这样比较好理解?) 其实线段树是一棵二叉搜索树. 以前我们树上的每一个结点存的是当前结点的权值,但是现在,我们的每一个结点上存的是 每一个区间 的 信息 (注意:这个信息可以是多种多样的!譬如可以是当前区间之内的权值之和, 之差(我才不会说我不会之差) ,最大值,最小值等等一系列 恶心人的东西 ) 1)线段树是一个 高效 处理 动态区间 的查询问题. 2)主要思想:二分. (较为模板?) 3)每个节点以结构体的方式存储

线段树 区间合并 F - Sequence operation

我的未来我决定 提交于 2019-12-17 01:08:19
F - Sequence operation 题解:这个题目不是一个特别难的题目,但是呢,写了好久,首先线段树难敲,其次就是bug难找,最后这个代码都被我改的乱七八糟的了,这个有两个地方要注意一下,一个是取反的lazy标志,每次取反都是对1取异或,还有一个也是这个取反的lazy标志,这个标志再第一种操作之后要进行消除。 #include <cstdio> #include <cstdlib> #include <queue> #include <algorithm> #include <vector> #include <cstring> #include <string> #include <iostream> #include <stack> #define inf 0x3f3f3f3f using namespace std; const int maxn = 1e6 + 100; struct node { int sum; int max_sub, max_zero; int l, r, len; int lazy1, lazy2; int max_prezero, max_lastzero; int max_preone, max_lastone; }tree[maxn * 4]; int a[maxn]; void push_up(int id) { tree[id]

【专题】线段树

六月ゝ 毕业季﹏ 提交于 2019-12-17 00:34:12
单点更新 最最基础的线段树,只更新叶子节点,然后把信息用PushUP(int r)这个函数更新上来。 hdu1166 敌兵布阵 线段树 hdu 1166 敌兵布阵 单点更新区间求和 hdu1754 I Hate It 线段树 hdu 1754 I Hate It 单点更新 区间求最值 hdu1394 Minimum Inversion Number hdu 1394 Minimum Inversion Number 线段树 逆序数 hdu2795 Billboard hdu 2795 Billboard 线段树 单点更新 UVa 12299 - RMQ with Shifts 线段树 单点更新 poj2828 BuyTickets poj2886 Who Getsthe Most Candies? hdu4288 Coder CF85-DSum of Medians CodeforcesBeta Round #19 D. Points poj2481 Cows hdu3950 Parking Log hdu4521 小明系列问题——小明序列 CodeforcesBeta Round #99 (Div. 1) C Mushroom Gnomes - 2 成段更新 需要用到延迟标记(或者说懒惰标记),简单来说就是每次更新的时候不要更新到底

【讲●解】超全面的线段树:从入门到入坟

隐身守侯 提交于 2019-12-16 14:42:58
\(Pre\) :其实线段树已经学了很久了,突然想到线段树这个数据结构比较重要吧,想写篇全面的总结,帮助自己复习,同时造福广大 \(Oier\) ( 虽然线段树的思维难度并不高 )。本篇立志做一篇最浅显易懂,最全面的线段树讲解,采用 \(lyd\) 写的《算法竞赛进阶指南》上的顺序,从最基础的线段树到较深入的主席树,本篇均会涉及,并且附有一定量的习题,以后可能会持续更新,那么现在开始吧! 目录一览 更新日志 线段树想 \(AC\) 之基本原理(雾*1 线段树想偷懒之懒标记(雾*2 线段树想应用之扫描线(雾*3 线段树想瘦身之开点与合并(雾*4 线段树想持久之主席树(雾*5 线段树想带修之树套树(雾*6 线段树想...不,你不想 更新日志 5.19 update:懒标记20%完成。 5.12 update:添加题目链接, 然后颓去了 。 5.11 update:修改部分字词,基本原理基本完成,大纲完成。 5.4 update:基本原理20%完成。 线段树想 \(AC\) 之基本原理 什么是线段树啊? 首先,你得有 树 的基本知识。 然后。 以下内容摘自百度百科 线段树是一种 二叉搜索树 ,与 区间树 相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树的一个结点。 很懵?没关系,我们继续。 其实,线段树( \(Segment\) \(Tree\)

线段树专题

烂漫一生 提交于 2019-12-15 23:56:10
A - Balanced Lineup 《最值查询》 POJ - 3264 给你一个长度为n的序列a[N] (1 ≤ N ≤ 50000),询问Q(1 ≤ Q ≤ 200000) 次,每次输出【L, R】区间最大值与最小值的差是多少。 so easy~ so easy~ so easy~ Input 多组用例 第一行是两个整数 N,Q 然后是N个数a[i] 保证a[i] 都小于1e9 然后是Q个询问 每次给你L,R 保证(1<=L<=R<= N) Output输出每次询问【L, R】区间最大值与最小值的差是多少Sample Input 6 3 1 7 3 4 2 5 1 5 4 6 2 2 Sample Output 6 3 0 #include <iostream> #include <cmath> #include <algorithm> #include <vector> #include <set> #include <map> #include <queue> #include <cstdio> #include <cstdlib> #define ll long long #define inf 0x3f3f3f3 using namespace std; const int mxn = 5e4+10; #define TLE std::ios::sync_with

BZOJ-2243【SDOI2011】染色&洛谷P2486(线段树区间合并+树链剖分)

两盒软妹~` 提交于 2019-12-14 01:42:58
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2243 洛谷: 时间限制 1.00s 内存限制 125.00MB BZOJ: Time Limit: 20 Sec Memory Limit: 512 MB Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1、将节点a到节点b路径上所有点都染成颜色c; 2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如“112221”由3段组成:“11”、“222”和“1”。 请你写一个程序依次完成这m个操作。 Input 第一行包含2个整数n和m,分别表示节点数和操作数; 第二行包含n个正整数表示n个节点的初始颜色 下面 行每行包含两个整数x和y,表示x和y之间有一条无向边。 下面 行每行描述一个操作: “C a b c”表示这是一个染色操作,把节点a到节点b路径上所有点(包括a和b)都染成颜色c; “Q a b”表示这是一个询问操作,询问节点a到节点b(包括a和b)路径上的颜色段数量。 Output 对于每个询问操作,输出一行答案。 Sample Input 6 5 2 2 1 2 1 1 1 2 1 3 2 4 2 5 2 6 Q 3 5 C 2 1 1 Q 3 5 C 5 1 2 Q 3 5 Sample Output 3 1

P3372 【模板】线段树 1

橙三吉。 提交于 2019-12-13 21:20:08
Miku ------------------------ 线段是是一种非常重要的数据结构,尤其在暴力时候 ------------------------- 线段树我觉得就是一个暴力的暴力的暴力数据结构,支持许多操作,比如说最大值,最小值,区间加,区间和等 ------------------------ 线段树的优化关键在于一个懒标记 ------------------------ 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 struct kk{ 6 int l,r;//每一个节点包含的左右区间 7 long long add,tql;//每一个节点的lazy和区间和 8 }t[10000005]; 9 long long n,m,a[10000005],p,x,y,pp; 10 void build(int x,int y,int z){ 11 t[x].l=y; t[x].r=z;//这个点的控制的左右区间 12 if(y==z){//一开始,只有叶节点赋值 13 t[x].tql = a[y]; 14 return ; 15 } 16 int midd =(y+z)>>1;//中间点,因为线段树就是从中间开始分裂的 17 build(2*x