线段树

动态开点 加 权值线段树

蓝咒 提交于 2019-12-05 07:42:03
~~### 小萌新 什么也不会 写得详细一些吧 ~~ 【[BJOI2016]回转寿司】 首先,暴力查找--30分 然后,黑科技---权值线段树 s[]表示前缀和,题目要求的是有多少对(i,j)满足L≤s[j]-s[i]≤R(i<j),变形一下得到s[j]-R≤s[i]≤s[j]-L 因此我们只需要遍历一遍s[]数组,每次对于当前的前缀和s,我们先在线段树上查询区间[s-R,s-L]内有多少个数,然后再把s加入到线段树中,最终求和即可 参考 https://blog.csdn.net/blessLZH0108/article/details/77072022 一般的线段树储存一段线段的信息, 然后这里维护的是单纯的数字,其实本质上没啥差别、、 一般数字比较大,我们就要考虑动态开点, 因为只有当用到时才开,会节省很大空间, 对于这道题是n*log(1e14) 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int maxn=1e5+50; 5 int tot; 6 const ll inf=10000000000+50; 7 ll rt; 8 ll lson[maxn*40*4],rson[maxn*40*4]; 9 struct tre 10 { 11 long long

hdu 2795 线段树

a 夏天 提交于 2019-12-05 02:13:59
At the entrance to the university, there is a huge rectangular billboard of size h*w (h is its height and w is its width). The board is the place where all possible announcements are posted: nearest programming competitions, changes in the dining room menu, and other important information. On September 1, the billboard was empty. One by one, the announcements started being put on the billboard. Each announcement is a stripe of paper of unit height. More specifically, the i-th announcement is a rectangle of size 1 * wi. When someone puts a new announcement on the billboard, she would always

模板 - 数据结构 - 线段树/SegmentTree

牧云@^-^@ 提交于 2019-12-04 18:19:48
struct SegmentTree { #define ls (o<<1) #define rs (o<<1|1) static const int MAXN = 100000; ll a[MAXN + 5]; ll st[(MAXN << 2) + 5]; void PushUp(int o) { st[o] = st[ls] + st[rs]; } void Build(int o, int l, int r) { if(l == r) st[o] = a[l]; else { int m = l + r >> 1; Build(ls, l, m); Build(rs, m + 1, r); PushUp(o); } lazy[o] = 0; } void Update(int o, int l, int r, int p, ll v) { if(l == r) { st[o] += v; return; } else { int m = l + r >> 1; if(p <= m) Update(ls, l, m, p, v); if(p >= m + 1) Update(rs, m + 1, r, p, v); PushUp(o); } } ll Query(int o, int l, int r, int ql, int qr) { if(ql <= l && r <=

SegmentTree-Complete 线段树完全版

北战南征 提交于 2019-12-04 16:40:21
线段树完全版关键词: 延迟加载、懒标记Lazy Tag 单点更新的情况比较简单。请看 线段树基础版 下面说说区间更新的情况。 场景是这样的,还是刚刚的数,求区间的和。 #define lson rt<<1 #define rson rt<<1|1 #define len (r-l+1) //(l,r)区间的长度 这次是区间更新,我们要用到区间的长度 建树 build和pushUp不变。我们把树建立好打印一下: [1]:36 [2]:26 [3]:10 [4]:15 [5]:11 [6]:10 [7]:0 [8]:6 [9]:9 [10]:5 [11]:6 [12]:8 [13]:2 [14]:0 pushDown 重点 延迟加载、懒标记思想: 假设现在要把区间【2,6】里5个数全加10,求总和。会数学的都知道,一共加了50,总和变成86。就是说对一段区间的统一操作,不需要对区间里的单个点进行改动。 只改动他们的老祖宗,并 在他们的祖宗上做一个标记 。以后啥事需要用到儿子了,一看父亲上有标记,就知道这个儿子还需要被更新。 下面的代码就是根据父亲rt,和对应的区间长度l,往下pushDown懒标记。 void pushDown(int rt,int len){// if(lazy[rt]){//这个点有lazyTag才往下下发lazyTag //lazyTag里存的值是"要延迟加载的

I - Defeat the Enemy(线段树好题)

自古美人都是妖i 提交于 2019-12-04 16:37:47
题目链接 Long long ago there is a strong tribe living on the earth. They always have wars and eonquer others. One day, there is another tribe become their target. The strong tribe has decide to terminate them!!! There are m villages in the other tribe. Each village contains a troop with attack power EAttacki , and defense power EDefensei . Our tribe has n troops to attack the enemy. Each troop also has the attack power Attacki , and defense power Defensei . We can use at most one troop to attack one enemy village and a troop can only be used to attack only one enemy village. Even if a troop

CSP-S2019游记

北战南征 提交于 2019-12-04 14:06:50
这是一个HB高二退役菜鸡选手的游记。 DAY0 去华科试机了。 本来想码线段树+匈牙利+Tarjan+SPFA的,结果只码出来一个洛谷模板线段树1,还wa了3发,成功为明天攒RP。 左边徐某灿上来就是一个NTT+树剖,右边 Bjpers2 5分钟码出一行版线段树,然后下了30分钟的国际象棋,我在一旁看着当场自闭。 晚上回来看了广饶一中OJ上的一套QWQ比赛题,和v-happy一起口胡出了T1和T2,但是都A不动(口胡之王*2)。 好像听说HB女队周傲然退役了?不清楚真实情况。 DAY1 留坑。 来源: https://www.cnblogs.com/thedreammaker/p/11869600.html

【LeetCode解题总结】数组/字符串篇

微笑、不失礼 提交于 2019-12-04 13:25:39
基本数据结构 数组/字符串 优点 构建非常简单 能在 O(1) 的时间里根据数组的下标(index)查询某个元素 小写字母一共就 26 个 缺点 构建时必须分配一段连续的空间 查询某个元素是否存在时需要遍历整个数组,耗费 O(n) 的时间(其中,n 是元素的个数) 删除和添加某个元素时,同样需要耗费 O(n) 的时间 性质 长度为n的字符串,共有n×(n + 1) / 2 + 1 个子串,2n个子序列 应用场景 考虑是否应当采用数组去辅助你的算法时,请务必考虑它的优缺点,看看它的缺点是否会阻碍你的算法复杂度以及空间复杂度 常见解题思路 数组 注意事项 总结规律时注意边界条件(例如,比较两个元素的大小时,要注意只有1个元素输入的情况) 具体方法 滑动窗口法 LeetCode 滑动窗口(Sliding Window)类问题总结 题目 思路 3. 无重复字符的最长子串 340. 至多包含 K 个不同字符的最长子串 指针法 每定义一个指针都要注意它指向的具体位置,是否可能越界 字符串 注意事项 注意区分String,char和StringBuilder 具体方法 高精度计算 字符串变换 6. Z 字形变换 :找出字符串前后每个字符的映射关系 高级数据结构 前缀树 性质 每个节点至少包含两个基本属性 children:数组或者集合,罗列出每个分支当中包含的所有字符 isEnd:布尔值

@codeforces - 932F@ Escape Through Leaf

混江龙づ霸主 提交于 2019-12-04 11:58:01
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 n 个点的树(标号1~n),以结点 1 为根。每个结点有两个点权 ai 与 bi。 你可以从一个点出发跳到它的子树中的某个结点去(不能跳到自己)。 从 x 跳到 y 所花费的代价为 ax * by,跳跃的总代价为每次跳跃的代价之和。 对于每个结点,计算从它出发跳到某一叶子结点的最小代价和。 Input 第一行包含一个整数 n (2 ≤ n ≤ 10^5),表示树中的结点数量。 第二行包含 n 个整数 a1, a2, ..., an (-10^5≤ai≤10^5)。 第三行包含 n 个整数 b1, b2, ..., bn (-10^5≤bi≤10^5)。 接下来 n-1 行每行包含两个整数 ui 和 vi (1≤ui, vi≤n),描述了树中的一条边。 Output 输出 n 个空格分开的整数,第 i 个描述了从第 i 个结点跳到叶子结点的最小代价和。 Examples Input 3 2 10 -1 7 -7 5 2 3 2 1 Output 10 50 0 Input 4 5 -10 5 7 -8 -80 -3 -10 2 1 2 4 1 3 Output -300 100 0 0 @solution@ 本题方法很多,可以转成 dfs

线段树模板总结

孤人 提交于 2019-12-04 11:07:50
本文只总结一下线段树的 易错点 (毕竟这玩意我早就会了) 重点: 线段树tag的意义 线段树开4倍空间的意义 注释里都有。 update 函数任务清单 pushdown 递归到子区间 pushup query 函数任务清单 pushdown 递归到子区间 //线段树不能严格开4倍空间, 要开大于等于MAXN的最小2的幂次的4倍空间 //如:MAXN = 10000, 则要开 16384*4 的空间。 #include<bits/stdc++.h> using namespace std; #define ll long long const int MAXN = 550005; ll sum[MAXN], tag[MAXN]; //tag表示:这个区间已处理过,但它的子区间还没有。 void pushdown(ll o, ll l, ll r) { ll ls, rs, mid; if(tag[o] == 0) return; ls = o << 1; rs = ls + 1; mid = (l+r) >> 1; sum[ls] += tag[o] * (mid - l + 1); sum[rs] += tag[o] * (r - mid); tag[ls] += tag[o]; tag[rs] += tag[o]; tag[o] = 0; } ll query(ll o, ll

数据结构总结

浪子不回头ぞ 提交于 2019-12-04 10:47:37
数据结构模块总结归纳 [TOC] 【前言】 临近CSP二轮,做一些总结归纳,就当作是复习吧。加油吧! 【目录】 (注:标*号为重要) 栈 单调栈 队列 单调队列 双端队列 邻接表 *堆 对顶堆 优先队列 并查集 扩展域 边带权 连通性 树状数组 权值树状数组 二维树状数组 *线段树 多标记下传 权值线段树 扫描线 线段树合并 分块 STL set vector map 题型总结和综合归纳 【栈】 最简单基础的一类数据结构,但是熟练掌握也能玩出朵花来。比如双栈排序之类的。 用途:一般用于一些先入后出的常规操作,如表达式计算、递归、找环等一系列常规操作。 实现:鉴于STL的stack常常爆空间,而且还不如手写快,因此我们更常使用手写栈。 代码就不贴了。 单调栈 【队列】 也是很基础的一个数据结构,适用范围及其广泛,用处花样繁多。 用途:~~太多了。~~比如BFS、各种序列问题、各种数据结构问题。 实现:上界较大时不宜使用STL的queue,不过一般情况下推荐使用,毕竟简洁且不易错。 初学的时候的手写队列BFS: void bfs(int i,int j) { int head=0,tail=1; q[tail].x=i;q[tail].y=j; pre[tail]=tail; memset(vis,0,sizeof(vis)); do { head++; for(int i=0;i<4