luogu P2574 XOR的艺术 (线段树) 算是比较简单的线段树. 当区间修改时.\(1 xor 1 = 0,0 xor 1 = 1\)所以就是区间元素个数减去以前的\(1\)的个数就是现在\(1\)的个数. #include <iostream> #include <cstdio> #define lson now << 1 #define rson now << 1 | 1 const int maxN = 2e5 + 7; struct Node…
P3373 [模板]线段树 2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含三个整数N.M.P,分别表示该数列数字的个数.操作的总个数和模数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x y k 含义:将区间[x,y]内每个数乘上k 操作2: 格式:2 x…
P3372 [模板]线段树 1 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k 操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的…
P3459 [POI2007]MEG-Megalopolis 题意 题目描述 Byteotia has been eventually touched by globalisation, and so has Byteasar the Postman, who once roamedthe country lanes amidst sleepy hamlets and who now dashes down the motorways. But it is those strolls inthe…
手动博客搬家: 本文发表于20170821 14:32:05, 原地址https://blog.csdn.net/suncongbo/article/details/77449455 URL: (Luogu) https://www.luogu.org/problem/show?pid=1198, (BZOJ)http://www.lydsy.com/JudgeOnline/problem.php?id=1012 题目大意: 给定一个数列,开始为空.维护两种操作: (1) Q L表示查询当前数列…
Luogu P3834 可持久化数据结构就是支持在历史版本上进行查询和修改操作的数据结构. 主席树就是对线段树的改进,使之可持久化. 前置知识:动态开点线段树 我们利用权值(值域)线段树统计区间内的数出现的次数. (权值线段树类似于线段树+桶) 那么我们可以对每一个位置建立一棵线段树,维护\(1\)~\(i\)的数据在一个区间上出现的次数. 求\(a[l...r]\)第k小,可以令第\(r\)棵线段树在区间\([x,y]\)上出现的次数减去上第\(l-1\)棵的线段树在区间\([x,y]\)上出…
(因为没有认证,所以这道题就由Froggy上传) 线段树分裂用到的地方确实并不多,luogu上以前也没有这道模板题,所以就出了一道,实在是想不出怎么出模板了,所以这道题可能可以用一些其他的算法水过去. 前置芝士 线段树: 本题中用到的是权值线段树(查询每个数在序列中出现的次数,序列中第k大的数等操作). 线段树合并: 为了增加一下码量才放上的. 线段树分裂 既然是模板题,这个自然才是重点. 以下这样一颗线段树: 需要将橙色线段覆盖的部分分裂出来,需要建一颗新的树,当一个节点所代表的区间与需要分裂…
题面 传送门:https://www.luogu.org/problemnew/show/P2824 Solution 这题极其巧妙. 首先,如果直接做m次排序,显然会T得起飞. 注意一点:我们只需要找到一个数. 所以说,我们可以考虑一个绝妙的想法:我们可以用二分答案的方法缩小要找的数的区间. 考虑二分一个值,判定p位置的数排序之后,p位置上的数是否>=mid 如果>=mid,则向右找,否则向左找. 怎么判定p位置的数排序之后是否>=mid呢? 考虑这样做:扫描一遍原数组,>=mi…
题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含三个整数N.M.P,分别表示该数列数字的个数.操作的总个数和模数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x y k 含义:将区间[x,y]内每个数乘上k 操作2: 格式:2 x y k 含义:将区间[x,y]内…
题目链接 \(Click\) \(Here\) 李超线段树的模板.但是因为我实在太\(Naive\)了,想象不到实现方法. 看代码就能懂的东西,放在这里用于复习. #include <bits/stdc++.h> using namespace std; const int N = 100010; #define ls (p << 1) #define rs (p << 1 | 1) #define mid ((l + r) >> 1) struct Nod…
题解 是我从来没有做过的裂点splay... 看的时候还是很懵逼的QAQ. 把最后一列的$n$个数放在一个平衡树中, 有 $n$ 个点 剩下的$n$行数, 每行都开一个平衡树,开始时每棵树中仅有$1$个点, 记录了开始时的区间左端点 $1$ 和右端点$m - 1$. 这样每次出队都最多只会影响两棵平衡树, 其中一颗为表示最后一列的平衡树. 然后就可以分成两种情况进行处理 1. $y = m$ 即出队的人位于最后一列,那么仅会影响最后一列的那颗平衡树, 删除位于第$x$个位置的点, 再插入到最后即…
据说某谷数据十分水...但幸好BZOJ上也过了...话说我记得讲课时讲的是奇奇怪怪的离散化..但现在突然觉得什么都可以线段树瞎搞了...QAQ 直接就是这个区间有没有被覆盖,被覆盖直接return: 如果出现修改,那么就说明它能被看见,++ans 短的一批的线段树(去了不必要的操作码量还是很小的...) #include<cstdio> #include<iostream> #define R register int #define ls (tr<<1) #defin…
咕咕了...于是借鉴了小粉兔的做法ORZ... 其实就是维护最大子段和的线段树,但上面又多了一些操作....QWQ 维护8个信息:1/0的个数(sum),左/右边起1/0的最长长度(ls,rs),整段区间中1/0的连续最长长度(mx). 于是对于各个操作,我们有了一些tag... tg1[]是区间赋值标记,没有标记时为-1,有标记时为0或1:tg2[]是区间取反标记,没有标记时为 0,有标记时为1. 注意标记下传时要先传tg1[],再传tg2[],否则取反标记会被赋值标记覆盖 #include<…
题目链接 神奇的线段树合并qwq   不过就思路而言很好想…… 观察到一棵树无论怎么交换两棵左右子树,子树内部的最优逆序对并没影响……决策只影响左右子树之间的逆序对…… 于是线段树合并直接乱搞就好啦 #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cctype> #define mid ((l+r)>>1) #defin…
题目链接 这题……我从一开始就想歪了qwq. 为了缅怀逝去的一小时我就把我的30分暴力思路放上来. 首先我们观察枚举的区间.假设我们要枚举的范围是1~5之间的四条路,为了方便我们把它们叫做abcd. 那么观察我们枚举的区间. a ab abc abcd b bc bcd c cd d 观察有一些区间是可以合起来的. 然后观察a出现4次,b出现6次,c出现6次,d出现4次. 是有一定规律的qwq 然后就$\frac{nm}{2}的复杂度搞搞 就三十分 正确思路是,观察一条路选不选上(设这条路左点x…
题目传送门 据说可以用贪心做?算了算了...我都不会贪.... 开始想的是用线段树,先建出一颗空树,然后输进区间操作后就维护最大值,显然开始我忽视了班车的容量以及可以有多组奶牛坐在一起的信息. 我们肯定想要有更多的区间被选中,根据线段覆盖问题的套路,我们要优先选结束位置最小的,能选就选,但是需要判断下能不能选,就是比较下当前区间最大值和容量的关系,尽量加上,进行修改.说白了就是在维护带修改的区间最大值. Code #include<cstdio> #include<algorithm&g…
Code: #include<bits/stdc++.h> #define maxn 300002 #define ll long long using namespace std; void setIO(string s) { string in=s+".in"; string out=s+".out"; freopen(in.c_str(),"r",stdin); freopen(out.c_str(),"w"…
线段树版的海报 实际上这个与普通的线段树相差不大,只是貌似数据太水,暴力都可以过啊 本来以为要离散的,结果没打就A了 #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int Max=40000001; struct Node{ int x,y,id; }node[10001]; int n,m,sum[Max],lazy[Max],tot[1001]; vo…
传送门 解题思路 线段树打标记,刚开始想复杂了,维护了四个标记.后来才知道只需要维护一个最大值最小值即可,然后更新的时候分类讨论一下. 代码 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> using namespace std; const int MAXN = 2000005; inline int rd(){ int x=0,f=1;char ch=getc…
LINK:情报中心 神题! 写了一下午 写到肚子疼. 调了一晚上 调到ex 用的是网上dalao的方法 跑的挺快的. 对于链的暴力 我不太会kk. 直接说正解吧: 分类讨论两种情况: 1 答案的两条链的LCA不重合. 2 答案的两条链的LCA重合了. 会造成这两种讨论是因为我们无法确定如果LCA重合了 固定那条重合的链 另外一个方向上的那两条链是否重合了. 其他blog里有配图 我就不放了直接口胡. 前者维护一下两条链第一次重合的地方. 然后使用线段树合并的时候来统计答案. 这个地方要注意细节的…
LINK:地图 考虑如果是一棵树怎么做 权值可以离散 那么可以直接利用dsu on tree+树状数组解决. 当然 也可以使用莫队 不过前缀和比较难以维护 外面套个树状数组又带了个log 套分块然后就可以了. 最暴力的当然是线段树合并了. 此时考虑这是个仙人掌 仔细画图 发现一些比较好的性质 某个点x 除了自己某个儿子的low比自己的dfn小 剩下的都大. 剩下的显然都可以造成贡献 利用dfn和low可以轻松判断 然后上线段树合并即可. 省空间的话可以直接离线 当然也可以在线做. 不过这个做法不…
前言: 当时考场上并没有想出来...后来也是看了题解才明白 解析: 大家(除了我)都知道,奇点和偶点会成对出现,而出现的前提就是建筑的高度突然发生变化.(这个性质挺重要的,我之前没看出来) 所以就可以扫一遍,然后就搞定了. 然后还有一个小点,要把每个区间搞成左闭右开,否则碰到诸如 (3,7,5)和(5,8,9) 这样的数据,中间的空隙就不会被计算. 然后写个线段树维护一下就ok了 代码 #include <bits/stdc++.h> using namespace std; const in…
要最优?就要一步到位,不能做"马后炮",走"回头路",因此将序列映射到一个假定最优序列,发现移动原序列等价于删除原序列元素,以便生成最大不下降子序列.可线段树维护. #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <cmath> #d…
题面传送门 我们可以画图找规律 这里没图,要看图可以去看M_sea dalao的题解(逃 可以发现单个节点\(i\)对答案的贡献为该节点的点权\(*\frac{1}{2^{dep_i}}\)(\(dep_i\)为从上往下\(i\)节点所在的层数-1,也就是深度,令根节点的\(dep=0\)) 我们可以发现,所有叶子节点的深度都是最大深度(记为\(ma\))或者最大深度-1,所以除开最下面一层,从上往下第\(i\)层的贡献都是序列中所有数之和\(*\frac{1}{2^{i-1}}\),最下面一层…
此题一看便是RMQ问题,但是由于开平方的特殊操作,tag操作失效 此时发现特性:sqrt最多执行6此便使值到达1/0,此时可以剪枝不进行该操作,利用并查集到达特性找根,根代表还可以进行操作的点,再利用树状数组简单的操作便可以AC #include<bits/stdc++.h> #define rep(i,x,y) for(register ll i=x;i<=y;i++) #define ll long long using namespace std; ; inline ll read…
题目链接:https://www.luogu.org/problemnew/show/P3373 题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每一个数的和 输入格式: 第一行包含三个整数N.M.P,分别表示该数列数字的个数.操作的总个数和模数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x y k 含义:将区…
题目传送门 今天非常想再看一遍霸王别姬想不进去题于是开始刷数据结构 注意到至多只有\(30\)种颜色,啊啊啊啊我一开始竟然想的不是状态压缩而是在线段树中存一个30大小的数组,这样每次更新的时候暴力循环一遍.hhhhh. 可能这样比较好想吧,但是比正解状态压缩一下不知道差到哪里去了:).开始还智障地把每次循环的次数开成30,那给出的色板数有什么用hh,这样是80分,改后AC. #include<cstdio> #include<algorithm> #define maxn 1000…
只会两个$log$的$qwq$ 我们二分答案:设答案为$ans$,则我们把$a[i]<=ans$全部设成$0$,把$a[i]>ans$全部设成$1$,扔到线段树里,这样区间排序(升序)就是求出$[l,r]$中$0$(或$1$)的个数$cnt$,然后对区间$[l,l+cnt-1]$赋值为$0$,对$[l+cnt,r]$赋值为$1$.最后查一下所求位置是$0$还是$1$来决定上下界改变方向. #include<cstdio> #include<iostream> #defi…
LINK:基站选址 md气死我了l达成1结果一直调 显然一个点只建立一个基站 然后可以从左到右进行dp. \(f_{i,j}\)表示强制在i处建立第j个基站的最小值. 暴力枚举转移 复杂度\(n\cdot k^2\). 考虑如何求一个区间中的贡献 显然我们需要把每个点的左右给求出来 这个其实可以利用二叉堆来维护左端点/右端点. 发现多次调用 考虑优化 利用邻接表即可. 容易想到利用数据结构来优化. 可以发现 不断向右的过程中只要把每个点的贡献在线段树上表达出来即可. 这点很容易得到 不再赘述.…
qwq #include<cstdio> using namespace std; ; int n,m,x,y,flag; *maxn],r[*maxn]; *maxn],sum[*maxn]; void build(int L,int R,int now) { lazy[now] = ; l[now] = L; r[now] = R; if(L == R) { scanf("%lld",&sum[now]); return; } ; build(L,mid,now…