BZOJ 3339 线段树】的更多相关文章

思路: 考虑离线处理 显然 l固定时 r越大 ans越大 那我们不妨按照l从小到大排序 l->l+1的时候 l到next[l]这段区间都跟a[l]取min就好了 搞颗线段树维护一下 //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 222222 #define inf 0x3f3f3f3f int n,q,a…
我原来准备做方差的.. 结果发现不会维护两个标记.. 就是操作变成一个 a*x+b ,每次维护a , b 即可 加的时候a=1 ,b=v 乘的时候a=v ,b=0 #include <cstdio> ; long long a[Maxn],n,P,l,r,c,m,type; struct Node { long long mul,add,sum,len; }tree[Maxn<<]; inline void Change(long long o,long long mul,long…
看错题目了,想成每个城市都可以买一个东西,然后在后面的某个城市卖掉,问最大收益.这个可以类似维护上升序列的方法在O(nlog^3n)的时间复杂度内搞定 这道题用到的一些方法: 1. 可以将有关的线段提取出来,然后一起处理. 2. 线段树可以维护两个方向的信息,这样就可以处理树上有序的东西. /************************************************************** Problem: 3999 User: idy002 Language: C++…
开方操作最多进行5次就可以把出现的任何数变成1. 所以用线段树暴力修改,以后修改时只需看一下是否当前区间都是0或1,如果是那么就直接返回. /************************************************************** Problem: 3211 User: idy002 Language: C++ Result: Accepted Time:1976 ms Memory:7068 kb ******************************…
本题将一道LCT的题特殊化(支持加边和删边,询问图的连通性),将图变成了2×m的网格图,然后就神奇地可以用线段树来维护. 对于每个区间[l,r],维护其四个角落之间的连通性(仅仅通过[l,r]这段的边构建起的连通性). 查询[l,r]时,先计算出[1,l-1],[l,r],[r+1,c]这三个线段的连通性,然后将[l,r]的四个角变成并查集的4个点,先用[l,r]中的6种关系更新,在看是否可以从左上角的点通过左边区间绕道左下角,以及从右上角通过右边区间绕道右下角,该并的并起来后直接看查询的点是否…
裸的线段树 /************************************************************** Problem: User: BLADEVIL Language: Pascal Result: Accepted Time: ms Memory: kb ****************************************************************/ //By BLADEVIL type rec =record left,…
先吐下槽,改了快一个小时,最后发现是SBT的delete写错了,顿时就有想死的心..... 首先对于这道题,我们应该先做一下他的小问题,bzoj1878,虽然和这道题几乎一点关系没有, 但是能给我们一个思路的启发 我们先考虑没有修改,只有区间询问 内个我下面的糖果是画笔的意思...我也不知道咋着题就读错了.... 那么对于一个糖果i,假设他的颜色是col,那么我们找到col颜色上一次出现的位置,为color[i], 那么对于一个区间L R里的color值,我们要找不同的颜色,那么假设一种颜色在L…
我们就建一颗线段树,线段树的每一个节点都是一颗平衡树,对于每个询问来说,我们就二分答案, 查询每个二分到的mid在这个区间里的rank,然后就行了 /************************************************************** Problem: User: BLADEVIL Language: Pascal Result: Accepted Time: ms Memory: kb **********************************…
非常裸的线段树  || 单调队列: 假设一个节点在队列中既没有时间优势(早点入队)也没有值优势(值更大),那么显然不管在如何的情况下都不会被选为最大值. 既然它仅仅在末尾选.那么自然能够满足以上的条件. 线段树 #include "stdio.h" #include "string.h" struct node { int l,r,Max; }data[800010]; int Max(int a,int b) { if (a<b) return b; els…
思路: 暴力建图有n*m条边 考虑怎么优化 (那就只能加个线段树了呗) 然后我就不会写了..... 抄了一波题解 //By SiriusRen #include <bits/stdc++.h> using namespace std; ,M=N*,inf=0x3f3f3f3f; vector<int>vec[N]; ,S=,T=; int lson[M],rson[M],root[N],jy,vis[M]; int read(){ ; ')p=getchar(); +p-',p=g…
思路: 1.最裸的线段树合并 2. 我们可以观察到子树求一个东西 那我们直接DFS序好了 入队的时候统计一下有多少比他大的 出的时候统计一下 减一下 搞定~ 线段树合并代码: //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; ; ],lson[N*],rson[N*],cnt,root[N]; int first[N],next[N]…
思路: 我们可以搞一棵线段树 对于一段区间有6种情况需要讨论 左上右下.左上右上.左下右下.左下右上 这四种比较好维护 用左上右下举个例子吧 就是左儿子的左上右下&左区间到右区间下面有路&右儿子的左下右下 或者是左儿子的左上右上&左区间到右区间上面有路&右儿子的左上右下 还有两种  区间的左(右)端点上下能不能联通 需要维护 这种就是左儿子的上下连通或(左上右上&左上右下&左到右两条路都联通&右儿子的上下联通) (假设c1<c2) 最后要查的是…
借鉴(抄)了一下题解-- 线段树合并的裸题吧- //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 4000050 typedef long long LL; int n,cnt,tree[N],son[N][2],root,Root[N],all,tr[N],s[N][2]; LL ans,ans1,ans2; v…
思路: 1.线段树合并(nlogn的) 2.splay+启发式合并 线段树合并比较好写 我手懒 //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=100050; int n,m,q,a[N],f[N],xx,yy,son[N*50][2],tr[N*50],root[N],cnt,rev[N]; char op…
思路: 可以把题目转化成 给你一些沿坐标轴方向的线段 让你求交点个数 然后就线段树+扫描线 搞一搞 (线段不包含断点 最后+n 这种方式 比线段包含断点+各种特判要好写得多) //By SiriusRen #include <cstdio> #include <algorithm> using namespace std; const int N=100005; int n,stkx[N],stky[N],topx,topy,top,tree[N*4];long long ans;…
思路: http://blog.csdn.net/wzq_QwQ/article/details/47152909 (代码也是抄的他的) 自己写得垃圾线段树怎么都过不了 隔了两个月 再写 再挂 又隔了10天 再写 终于A了---------.. //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define mod 10000000…
思路: 外围一个权值线段树 里面是个区间线段树 搞一个标记永久化 //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 100050 #define int long long int n,m,op,xx,yy,zz,cnt,root[N*16],lson[N*160],rson[N*160]; int tree[N*…
思路: 先搞出来每个点的DFS序 (要有入栈和出栈两种状态的) 处理出来 线段树区间有多少入栈的和多少出栈的 加区间的时候就加(入-出)*wei 查前缀和 //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 200050 #define int long long int n,m,Wei[N],v[N],first[…
思路: 权值线段树 (找中位数用的) 记录下出现的次数和sum 一定要注意 有可能中位数的值有许多数 这怎么办呢 (离散化以后不去重就行了嘛--.) (为什么他们想得那么麻烦) //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 100500 #define int long long int n,k,sum[N*1…
用树套树来解决这个问题,存储每个节点的数值是多少,然后交换 对于答案的变更可以讨论下,假设交换的是x,y位置的数x<=y 如果x=y || high[x]=high[y]则对答案没有影响 如果high[x]<high[y],那么首先交换x,y会对这两个点的逆序对数增加1,否则减小1 那么这是对于这两个数中间的数的逆序对的影响就是: x的移动会令在这个区间里比x权值小的数与x不在为逆序对,所以答案减少个数 同时令比x的权值大的数多一个与x的逆序对,所以答案增加个数. y类似,在此不再赘述 /**…
因为d>=0,所以一个位置的数只会单调不降并且只会有一次穿过0. 用这个性质,我们我可在线段树中记录正数负数的个数和和,以及最大的负数以及答案. 修改操作:如果当前最大负数+d<=0,那么就直接加到懒惰标记中,否则就暴力向下传递. 因为每个节点最多被额外访问该区间负数个数次,所以所有点总共会被额外访问O(nlogn)次,在加上修改操作和询问操作的普通访问O(mlogn)次,所以时间复杂度是有保证的. 谢谢mhy12345的讲解. /*******************************…
思路: 把询问离线下来,查询max和查询min相似,现在只考虑查询max 令sum[l,r,x]表示l到r内的数为左端点,x为右端点的区间询问的答案 那么询问就是sun[l1,r1,r2]-sum[l1,r1,l1-1] 从1到n枚举x,维护区间线段树表示sum[l,r,x],发现从x-1转移到x的过程中,每个数加上了max(a[pos]..a[x])的答案. 用单调队列维护一个单调递减的序列,由于a数列是随机的,这个队列期望有log个元素,所以只需要对这log段暴力修改,复杂度nlog^2n…
思路: 线段树表示的是时间 每回最多log个段 区间覆盖 一直到叶子 的线性基 xor 一下 就是答案 一开始没有思路 看了这篇题解 豁然开朗 http://www.cnblogs.com/joyouth/p/5333181.html (还是本省的前辈呢) //By SiriusRen #include <set> #include <vector> #include <cstdio> using namespace std; const int N=500000; i…
标记会重叠需要判断. #include <bits/stdc++.h> using namespace std; inline int Max(int x,int y) {return x>y?x:y;} inline int Max3(int x,int y,int z) {return Max(x,Max(y,z));} inline void Swap(int &x,int &y) {int t=x;x=y;y=t;} //=====================…
用8个bool维护即可分别为LURU,LURD,LDRU,LDRD,LULD,RURD,Side[1],Side[2]即可. Side表示这一块有没有接到右边.Merge一下就可以了.码农题,WA了一次,发现未初始化,就AC了.. #include <cstdio> inline int Min(int x,int y) {return x>y?y:x;} inline void Swap(int &x,int &y) {int t=x;x=y;y=t;} inline…
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 7163  Solved: 2587[Submit][Status][Discuss] Description 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和…
同是O(nlog^2n)怎么常数差距就这么大呢,,, 同是LCT  怎么我的和Po姐姐的常数差距就这么大呢 我绝对是脑子被驴踢了才写这个垃圾算法 //By SiriusRen #include <bits/stdc++.h> using namespace std; ; int n,m,q,xx,yy,zz,tim[N],cnt; int first[N],next[N],v[N],tot; ],rev[N],Q[N],top,opersize; ; char in[LIMIT],*p=in;…
(代码无比丑陋) //By SiriusRen #include <cstdio> #include <algorithm> using namespace std; int n,m,L,R,xx,tx,t,root[3000050],size,ans,op,inf=0x3fffffff,a[500050]; struct Treap{int ch[2],v,cnt,sz,rnd;}tr[3000050]; void Upd(int k){tr[k].sz=tr[tr[k].ch[…
思路: 我们很容易发现 一个数开根号 开几(很小)次 就到了1 1 再怎么开 都是1 由于这个性质 我们就可以用并查集 了 //By SiriusRen #include <cmath> #include <cstdio> #include <algorithm> using namespace std; #define int long long int n,m,tree[666666],f[111111],T,op,xx,yy; int find(int x){re…
[BZOJ2733]永无乡(线段树,并查集) 题面 BZOJ 题解 线段树合并 线段树合并是一个很有趣的姿势 前置技能:动态开点线段树 具体实现:每次合并两棵线段树的时候,假设叫做\(t1,t2\),其中要把\(t2\)合并进\(t1\)中 假设当前位置\(t1\)没有节点,则直接把\(t2\)的这个位置给\(t1\)(直接接上去就好啦) 如果\(t2\)这个位置没有节点,那么直接\(return\) 否则,两个位置都有节点,把两个节点的信息合并,然后递归合并左右子树 简单的代码如下: void…