线段树

ACM训练周末总结—9月3日

荒凉一梦 提交于 2019-12-01 03:43:15
一周很快就结束了, 虽然还算有点收获,但实在没法和暑假时候比。 线段树现阶段理解:其实线段树比树状数组还要简单,无非就是一棵二叉树,它主要可以把一组数据按照二分的方式存进二叉树,存树的方式我了解两种,一种是只利用一个一维数组,查找该树时要通过l,r来继续确定目标位置,另一种是利用结构体构造一个一维数组,这样数组下标就是二叉树的结点更加方便。另外在这段时间的学习,还了解到了“懒惰标记”,懒惰标记是为了节省时间而发明的,实际上就是让子结点暂时处于不更新的状态,用到的时候才更新,这样实现暂时结束继续向下搜索,节省了时间。另外今天做了计算区间颜色数量的题,利用线段树记录该区间下是否有多个颜色,如果有继续向下找,直到找到该区间下只有一种颜色,记录返回。 接下来一周计划,周一到周三无论多忙都要每天看懂最少两篇线段树博客,周四,周五看博客并尽量A出一道题,周六上午,晚上写作业复习主业课程,下午训练,周日训练一天。 来源: CSDN 作者: snayf 链接: https://blog.csdn.net/snayf/article/details/77825745

10月清北学堂培训 Day 2

杀马特。学长 韩版系。学妹 提交于 2019-12-01 02:52:27
今天是杨溢鑫老师的讲授~ T1 物理题,不多说(其实是我物理不好qwq),注意考虑所有的情况,再就是公式要推对! #include<bits/stdc++.h> using namespace std; typedef long long LL; const LL mod = 998244353; inline void rd(LL &x) { x=0;int f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} } LL n,m,x[2],y[2],g,ans; LL qpow(LL a) { LL res=1,k=mod-2; while(k) { if(k&1)res=res*a%mod; a=a*a%mod; k>>=1; } return res; } LL _2 = qpow(2); void down(LL x,LL h){x%=mod;h%=mod; ans += (x*x*m%mod)*qpow(4*h); ans%=mod;} void up(LL x,LL h) {x%=mod;h%=mod; ans += (m*h%mod) + ( (x*x*m%mod)

HDU-6547 Tree (树链剖分,线段树区间开根号)

折月煮酒 提交于 2019-12-01 02:41:36
题目链接: HDU-6547 Tree 题意 wls 有三棵树,树上每个节点都有一个值 $a_i$ ,现在有 2 种操作: 1. 将一条链上的所有节点的值开根号向下取整; 2. 求一条链上值的和; 链的定义是两点之间的最短路。 思路 树链剖分裸题,区间开根号可用线段树做,利用 $10^9$ 范围内的数经过少数几次开根号之后就会达到 1,标记线段树区间最大值,若为 1 则无需再往下更新。 树链剖分传送门: https://www.cnblogs.com/kangkang-/p/8486150.html 代码实现 #include <stdio.h> #include <iostream> #include <cmath> #define REP(i, a, b) for (int i = a; i <= b; i++) using namespace std; typedef long long LL; const double esp = 1e-8; const int MAXN = 110000; struct Node { int to, next; } edg[MAXN<<1]; struct segmentTree { int left, right; LL sum, maxx; } tree[MAXN<<2]; int head[MAXN], siz[MAXN], top

线段树

纵然是瞬间 提交于 2019-11-30 23:57:23
参考博客 : 线段树详解 算法作业的题目: 639.线段树-贴海报 (10分) C时间限制:3000 毫秒 | C内存限制:3000 Kb 题目内容: 由10^7块1x1的玻璃构成1x10^7的海报墙,每个海报完整地覆盖几块玻璃,海报的宽度可以不同。后来的人可以覆盖 前人的海报。一张海报如果有没被覆盖的部分,则称为可视海报。你的任务是找出有多少可视海报。 输入: 第一行是测试的总数c,接下来的行是各测试用例。 每个测试的第一行是海报的总数n, n<=10000, 然后是n个按先后顺序贴的海报的位置li, ri. 满足1<=li<=ri<=10^7。 输出描述 每个测试的可视海报数目 输入样例 1 5 1 4 2 6 8 10 3 4 7 10 输出样例 4 来源: https://www.cnblogs.com/young-children/p/11645181.html

hdu 1542 线扫描(线段树)+离散化 求覆盖面积

狂风中的少年 提交于 2019-11-30 22:57:17
// hdu1542 // 线扫瞄思想结合线段树求覆盖面积问题,也能求周长。具体如何线扫瞄 下面参考博客里面有 // 直接百度学的( 想破脑壳也只能是wa或者tle ) // 参考博客 HDU 1542 Atlantis(线段树:扫描线) // 不能算抄。。。 结合了多方代码得出我喜欢的写法。。。离散化区间问题只停留在听懂的层面上, 之前并查集区间离散化也是囫囵吞枣的学, 不能这样啊( ఠൠఠ )ノ 1 #include<cstdio> 2 #include<algorithm> 3 #define L k<<1 4 #define R k<<1|1 5 #define mid (tree[k].l+tree[k].r)>>1 6 using namespace std; 7 typedef long long ll; 8 const int MAXN = 200+5; 9 10 double X[MAXN]; 11 struct Edge { 12 double l, r; 13 double h; 14 int f; 15 Edge() {} 16 Edge(double l, double r, double h, int f):l(l),r(r),h(h),f(f) {} 17 bool operator < (const Edge &a) const { 18

hdu5642 snake(dfs序+线段树)(模板)

ε祈祈猫儿з 提交于 2019-11-30 20:01:03
Snacks Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 7726 Accepted Submission(s): 1681 Problem Description 百度科技园内有 n 个零食机,零食机之间通过 n − 1 条路相互连通。每个零食机都有一个值 v ,表示为小度熊提供零食的价值。 由于零食被频繁的消耗和补充,零食机的价值 v 会时常发生变化。小度熊只能从编号为0的零食机出发,并且每个零食机至多经过一次。另外,小度熊会对某个零食机的零食有所偏爱,要求路线上必须有那个零食机。 为小度熊规划一个路线,使得路线上的价值总和最大。 Input 输入数据第一行是一个整数 T ( T ≤ 10 ) ,表示有 T 组测试数据。 对于每组数据,包含两个整数 n , m ( 1 ≤ n , m ≤ 100000 ) ,表示有 n 个零食机, m 次操作。 接下来 n − 1 行,每行两个整数 x 和 y ( 0 ≤ x , y < n ) ,表示编号为 x 的零食机与编号为 y 的零食机相连。 接下来一行由 n 个数组成,表示从编号为0到编号为 n − 1 的零食机的初始价值 v ( | v | < 100000 ) 。 接下来

树状数组(小总结)

大兔子大兔子 提交于 2019-11-30 19:55:07
树状数组 经典应用类型 求区间[l ,r]的和(乘积等);修改单点的值 求单点的值,修改区间[l ,r]的值 (类似线段树) 特性 类似 线段树 ,但是常数更小,实现起来更简单,当然,功能不如线段树 数据结构 数组a[1…n]为原始数据 数组d[1…n]记录着区间和(乘积等) 数组d对应数组a的关系如下: 设节点编号为x,那么这个节点管辖的区间为2^k(其中k为x二进制末尾0的个数)个元素。因为这个区间最后一个元素必然为Ax, 所以很明显: d[n] = A(n – 2^k + 1) + ... + A[n] 实现方法 基本函数 计算 2^k 的函数 int lowbit ( int x ) { return x & ( - x ) ; } 插入操作(将a[n]加v,维护d数组) void modify ( int x , int v ) { /*Add v y a[x]*/ while ( x <= n ) { d [ x ] + = v ; x + = lowbit ( x ) ; } } 查询操作(返回区间[1…x]的和 前缀和 ) int query ( int x ) { /*Query from a[x] + ... + a[y]*/ int sum = 0 ; while ( x ) { sum + = d [ x ] ; x - = lowbit ( x ) ; }

[HEOI2016/TJOI2016]排序(01线段树)

我们两清 提交于 2019-11-30 19:50:49
洛谷 大于等于中间数为一 小于为0 二分查找 #include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } const int maxn=1e5+5; #define ls rt<<1 #define rs rt<<1|1 int n,m,a[maxn],k; bool tr[maxn<<2]; int lazy[maxn<<2]; int sum[maxn<<2]; struct node{ int l,r,type; }que[maxn]; inline void build(int rt,int l,int r,int x) { lazy[rt]=0; if(l==r) { sum[rt]=tr[rt]=(a[l]>=x); re ; } int mid=(l+r)>>1; build(ls

Test 1 T2 B 线段树合并

我怕爱的太早我们不能终老 提交于 2019-11-30 18:41:21
模拟赛的T2,多敲了两行成功爆掉~ 写线段树合并的时候一定要注意一下不能随意新开节点. code: #include <bits/stdc++.h> #define N 100009 #define ll long long #define setIO(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) using namespace std; int n,edges; int A[N],hd[N],to[N<<1],nex[N<<1],kk[N],rt[N],ans1[N]; ll val[N<<1]; ll ans2[N]; void add(int u,int v,int c) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c; } struct Segment_Tree { #define lson p[x].ls #define rson p[x].rs int tot; struct Node { int ls,rs,size; ll dis,num,rt,mul,maxx; }p[N*90]; int newnode() { return ++tot; } void mark(int x,ll d) { p[x].mul+=d; p[x]

二进制拆分线段树

青春壹個敷衍的年華 提交于 2019-11-30 18:18:47
noip 模拟20190907 T3 位运算(bit) /* reference: translation: solution: trigger: note: * record: date: 2019.09.04 */ #include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=a;i<=b;++i) #define dwn(i,a,b) for(int i=a;i>=b;--i) template <typename T> inline void rd(T &x){x=0;char c=getchar();int f=0;while(!isdigit(c)){f|=c=='-';c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}x=f?-x:x;} inline void write(int n){if(n==0)return;write(n/10);putchar(n%10+'0');} #define mem(a,b) memset(a,b,sizeof(a)) #define ee(i,u) for(int i=head[u];i;i=e[i].next) #define lson (o<<1)