【学习笔记】线段树详解(全)

和三个同学一起搞了接近两个月的线段树,头都要炸了T_T,趁心态尚未凉之前赶快把东西记下来。。。


【目录】

  • 【基础】作者:\((Silent\)_\(EAG)\)
  • 【懒标记】作者:\((Silent\)_\(EAG)\)
  • 【扫描线】作者:\((IC\)_\(QQQ)\)
  • 【权值线段树】作者:\((Xing\)_\(Ling)\)
  • 【动态开点】作者:\((Xing\)_\(Ling)\)
  • 【线段树合并】作者:\((Xing\)_\(Ling)\)
  • 【可持续化线段树—静态主席树】作者:\((Xing\)_\(Ling)\)
  • 【可持续化线段树—动态主席树(可修)】作者:\((Xing\)_\(Ling)\)

一:【基础姿势】

\(piao\) 一下隔壁大佬的文章QAQ: \(Silent\)_\(EAG\)

基础题走起:

  • 【模板】线段树 \(1\) \([P3372]\)
    【标签】线段树/树状数组
    【题解】\(Silent\)_\(EAG\)

  • \(Can\) \(you\) \(answer\) \(these\) \(queries\) \(I\) \([SP1043]\)
    【标签】线段树

  • \(Interval\) \(GCD\) \([CH4302]\)
    【标签】线段树/树状数组/\(GCD\)
    【题解】\(Silent\)_\(EAG\)

高档题走起:

  • \(Can\) \(you\) \(answer\) \(these\) \(queries\) \(III\) \([SP1716]\)
    【标签】线段树/懒标记
    【题解】\(Silent\)_\(EAG\)

  • 炸勃龙 \(I\) \([P4118]\) \([BZOJ5394]\) \(/\) 奈芙莲·卢可·印萨尼亚 \(Nephren\) \(Ruq\) \(Insania\) \([P3934]\)
    【标签】线段树/树状数组/暴力枚举/数论/欧拉定理
    (\(YNOI2016\) 毒瘤数论)


二:【懒标记】

见隔壁:\(Silent\)_\(EAG\)

基础题走起:

  • 【模板】线段树 \(2\) \([P3373]\) \(/\) 维护序列 \([P2023]\) \([BZOJ1798]\)
    【标签】线段树/懒标记
    【题解】\(Silent\)_\(EAG\)

高档题走起:

  • \(Can\) \(you\) \(answer\) \(these\) \(queries\) \(IIII\) \([SP2713]\)
    【标签】线段树/懒标记
    【题解】\(Silent\)_\(EAG\)

  • 市场 \([LOJ6029]\)
    【标签】线段树/懒标记
    【题解】\(Silent\)_\(EAG\)

  • 酒店 \(Hotel\) \([P2894]\) \([BZOJ1593]\)
    【标签】线段树/懒标记

  • 序列操作 \([P2572]\) \([BZOJ1858]\)
    【标签】线段树/懒标记/珂朵莉树
    (如果尝试用线段树做的话,懒标记的运用达到了毁天灭地的地步。而珂学就爽了,那么它就是道大水题)


三:【扫~描~线~】

见隔壁:\(IC\)_\(QQQ\)


四:【权值线段树】

 QAQ:以前似乎在某个地方看到过一个叫做做权值树状数组的东西唉QWQDL:其实他们都是一样的思想,只是不同的实现方式而已QAQ:可是XX在写过无数区间作业的题后,发现无论是哪一类,树状数组都比线段树快不止三倍唉QWQDL:*****

权值线段树是什么?

权值线段树,顾名思义是一颗线段树。
但它和普通线段树略有不同: 普通线段树维护的是一段区间的数值的总和或最大值等等...... 而权值线段树维护的是一定范围内某个数值出现的次数。实际上它和之前的权值树状数组是一样的原理。(求逆序对也可用权值线段树实现 )

它有什么用?

按照定义,我们可以用它对于权值进行计数,感觉有点像数位\(dp\)吧,求一定范围内符合要求的数的个数。权值线段树的\(“\)范围\(”\)是不定的,而\(“\)要求\(”\)一般是:在给定的数值范围内。

举个栗子:
有一个数列: \(a(1,1,2,3,3,4,4,4,4,5)\) 对其维护一个计数的权值线段树,树的大小就是数列的值域 \([mins~maxs]\),即 \([1~5]\)。

如图,在数列中:
数值 \(1\) 出现了 \(2\) 次
数值 \(2\) 出现了 \(1\) 次
数值 \(3\) 出现了 \(2\) 次
数值 \(4\) 出现了 \(4\) 次
数值 \(5\) 出现了 \(1\) 次

重要应用:

在此基础上,它还有一个很重要的作用 :
查询某区间内第 \(k\) 小或第 \(k\) 大的值。

引理:

如果在值域范围内 \((\) 即 \([mins~maxs]\) \()\)中发现有某个位置 \(x\),数列中存在这个数 \(x\),且使得数值范围在区间 \([mins~x]\) 内的数一共有 \(k\) 个,那么 \(x\) 就是 \(k\) 的数。
反之亦然:
如果在值域范围内 \((\) 即 \([mins~maxs]\) \()\)中发现有某个位置 \(x\),数列中存在这个数 \(x\),且使得数值范围在区间 \([x~maxs]\) 内的数一共有 \(k\) 个,那么 \(x\) 就是 \(k\) 的数。

【分析】

以查询第 \(k\) 小为例

我们可以用一种二分的思想,当需要在某个值域范围 \([l~r]\) 内查找第 \(k\) 小时,先计算出数值在 \([l~mid]\) 以内的数的个数 \(tmp\),再将其与 \(k\) 进行比较:

  • 如果 \(tmp \geqslant k\),则说明第 \(k\) 小的数应存在于 \([l~mid]\) 这个范围。
  • 如果 \(tmp \leqslant k\),则说明第 \(k\) 小的数应存在于 \([mid+1~r]\) 这个范围,而实际上就等价于在 \([mid+1~r]\) 中找到第 \(k-tmp\) 小的数。

【Code】

#define Re register int
#define pl tree[p].PL
#define pr tree[p].PR
inline int ask(Re p,Re L,Re R,Re k){//查询第k小if(L==R)return L;//边界叶节点 Re tmp=tree[pl].g;//计算左子树(数值范围在L~mid的数)共有多少个数字 if(tmp>=k)return ask(pl,L,mid,k);
//左子树已经超过k个,说明第k小在左子树里面 else return ask(pr,mid+1,R,k-tmp);
//左子树不足k个数字,应该在右子树中找到第(k-tmp)小
}

五:【动态开点】

什么是动态开点?

动态开点用法较固定,目的也很明确:节省空间。
它的实质其实就是在空间不够的情况下,把不需要的节点变成虚点。

有什么用?

求解逆序对时可以用权值树状数组,那么如果尝试用权值线段树做的话会出现什么后果呢?

肯定是可解的。但是,由于值域大多都是 \(inf\) 级别的数字,况且某些比较毒瘤的在线操作还没法离散化,于是在使用权值线段树时,一般都会伴随着动态开点的使用。

如何使用?

这里引用一下一位大佬的比喻: 开局一个根,枝叶全靠给。

当要用到(一般只有修改)某个节点的信息时,就手动开一个新的节点,给它一个点的空间包括各种节点信息。而在查询中如果发现进入的节点不存在(还没开发过),那么直接返回,不需要在查询时新建节点。

【空间复杂度】

\(Q*log(inf)\)。其中 \(Q\) 为修改次数。

【Code】

(基本框架)

int cnt;
inline void sakura(Re &p,Re L,Re R,Re ???){//【???修改】if(!p)p=++cnt,tree[p].?=???;
//发现进入了一个空节点,新建一个节点,赋予它编号,记录基本信息 if(L==R){tree[p].?=???;return;}
//达到叶子节点,记录一些特殊的信息,并返回 Re tmp=???;//可能会在在递归之前进行一些计算来方便判断 if(???)sakura(pl,L,mid,???);//递归进入左子树 if(???)sakura(pr,mid+1,R,???);//递归进入右子树 tree[p].?=???;//回溯后更新信息
}

六:【线段树合并】

什么是线段树合并?

简单来说就是将两棵线段树合并起来,并累加它们的信息。

有什么用?

线段树合并一般用于对树上信息的统计,例如:对一棵树的所有叶子节点都开一个线段树,统计信息时,将所有的儿子节点的线段树合并起来,得到父亲节点的线段树,再用其去合并统计祖先的信息。

【时间复杂度】

如果一棵线段树的所有节点都不为空(动态开点会使得虚点的存在),离散化后值域为 \(n\),递归一棵线段树树的时间复杂度达到最大: \(O(logn)\)。如果总共 \(n\) 棵树的所有节点都不为空,那么需要合并 \(n-1\) 次, 总时间复杂度达到最大: \(O(n*logn)\)。

【Code】

inline int merge(Re p,Re q){//【线段树合并】 if(!p)return q;if(!q)return p;//当需要合并的点的其中一个编号为0时 (即为空),返回另一个编号 tr[p].g+=tr[q].g,p;//把q合并到p上面去 pl=merge(pl,tr[q].lp);//合并左子树,并记录p点的左子树编号pr=merge(pr,tr[q].rp);//合并右子树,并记录p点的右子树编号return p;
}

基础题走起:

  • 晋升者计数 \(Promotion\) \(Counting\) \([P3605]\)
    【标签】DFS/离散化/树状数组/线段树/线段树合并/动态开点
    【题解】\(Xing\)_\(Ling\)

  • 永无乡 \([P3224]\) \([BZOJ2733]\)
    【标签】Splay/平衡树/线段树合并/DFS/权值线段树/并查集/离散化
    【题解】\(Xing\)_\(Ling\)

高档题走起:

  • \(ROT-Tree\) \(Rotations\) \([P3521]\) \([BZOJ2212]\)
    【标签】线段树/权值线段树/线段树合并
    【题解】\(IC\)_\(QQQ\)

七:【可持续化线段树—静态主席树】

来看一道经典的例题 【模板】可持久化线段树 \(1\) (主席树) \([3834]\) \(/\) \(K\)-\(th\) \(Number\) \([P3834]\) \([POJ2104]\) \([SP3946]\)

【题目大意】

给定一个长为 \(n\) 的数列以及 \(Q\) 个查询,每次查询输入两个整数 \(l\),\(r\),输出数列中 \(l\) ~ \(r\) 第 \(K\) 小的数。

【 分析】

此题有三个关键点:

  1. 求一棵数列中的第 \(K\) 大或第 \(K\) 小的数。
    解决方案:权值线段树

  2. 如果仅仅是这样,则非常好办,给出的询问是一段区间。一段长为 \(n\) 的数列中共有 \(n(n-1)/2\) 个不同的区间,如果给每个区间都开一个权值线段树,后果是:\(TLE\) \(+\) \(MLE\) \(+\) 初始化建树无从入手。
    解决方案:前缀和
    (对于原数列的每个位置都建立一个权值线段树,\(p[i]\) 表示第 \(i\) 个位置上的树的根节点编号,用 \(tree[pt[i]]\) 表示从第 \(1\) 个到第 \(i\) 个数这个区间中共 \(i\) 个数所维护成的一棵权值线段树。\(message[pt[i]]=\sum_{j=1}^i message[pt[j]]\))

  3. 可内存还是远远不够,即使是使用了【动态开点】 \(+\) 离散化,值域由 \(inf\) 降为 \(N\),每一棵权值线段树的节点数降为 \(N*2\),节点,但一共有 \(N\) 棵树,\(N*N*2\) 动辄就是几十万兆内存。(做一个简单的计算:
    \(200000*200000*2*4*3/1024/1024 \thickapprox 305175.78125 Mb\))
    解决方案:可持续化
    由于第 \(i\) 棵树 \(tree[pt[i]]\) 与第 \(i-1\) 棵树 \(tree[pt[i-1]]\) 只有 \(logn\) 个节点不一样,于是只需要对第 \(i-1\) 棵树进行一次单点修改将 \(a[i]\) 加入,就变成了第 \(i\) 棵树。因此我们可以由已经建好第 \(i-1\) 棵树迅速建立起第 \(i\) 棵树,这也就是主席树思想的精髓所在。
    说具体点,就是让第 \(i\) 棵树与第 \(i-1\) 棵树公用一些节点(因为在这些没有发生改变的部分,它们的信息是完全相同的),在递归过程建树中,如果发现要进行【单点修改】操作的是左子树,那就让新树的右子树编号指向旧树的右子树编号(即 \(tree[pt[i]].pr=tree[pt[i-1]].pr\) )然后递归进入左子树的建立,反之亦然。
    但第 \(1\) 棵树需要由第 \(0\) 棵树变化而来,当有特殊需要时,要提起把第 \(0\) 棵树建立完整,而道题不需要,因为第 \(0\) 棵树本来就为空,所以不用管。

【时间复杂度】

每次建树的过程都接近于【单点修改】, 为 \(O(logn)\) ,所以初始化建树的过程为 \(O(nlogn)\) 。

单次询问采用权值线段树中的【查询第 \(k\) 小】,为 \(O(logn)\)。

总共 \(Q\) 次询问,为 \(O(Qlogn)\) 。

总时间复杂度: \(O((n+Q)logn)\)

【空间复杂度】

如果要建立完整的第 \(0\) 棵树,会占用 \(n*2\) 个节点,每棵新树的建立都要新建 \(logn\) 个节点,一共有 \(nlogn\)。

总空间复杂度:\((logn+2)*n\)

【Code】

#include<algorithm>
#include<cstdio>
#define mid (L+R>>1)
#define pl tr[p].lp
#define pr tr[p].rp
#define Re register int
#define F(a,b) for(i=a;i<=b;++i)
using namespace std;
const int N=1e5+3;
int x,y,z,i,n,m,k,t,fu,cnt,a[N],b[N],pt[N];//pt[i]表示离散化后i这个位置所对应的权值树根的编号
struct QAQ{int g,lp,rp;}tr[N<<5];//权值树,保守开一个32*N
inline void in(Re &x){//【快读】自己动手,丰衣足食... x=fu=0;char c=getchar();while(c<'0'||c>'9')fu|=c=='-',c=getchar();while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();x=fu?-x:x;
}
inline int creat(Re pp,Re x,Re L,Re R){
//把上一棵权值树pp(即pt[a[i-1]])复制过来
//并在递归复制途中对x(即a[i]离散化后的位置)这个点同步进行单修操作 Re p=++cnt;pl=tr[pp].lp,pr=tr[pp].rp,tr[p].g=tr[pp].g+1;//新开一个点,并把上一个的数据复制进来,并使tr[].g++ if(L==R)return p;//到达边界: L==R(即x这个位置) if(x<=mid)pl=creat(tr[pp].lp,x,L,mid);//递归进入条件:单修else pr=creat(tr[pp].rp,x,mid+1,R);//注意tr[pp]要同时递归至左(右)子树 return p;
}
inline int ask(Re p,Re pp,Re L,Re R,Re k){
//查询。p为查询区间左端点的权值树根编号,pp为查询区间右端点的权值树根编号 if(L==R)return b[R];//边界:L==RRe tmp=tr[tr[pp].lp].g-tr[pl].g;//用前缀和思想计算出左子树共有多少个数字 if(tmp>=k)return ask(pl,tr[pp].lp,L,mid,k);//左子树已经超过k个,说明第k小在左子树里面 else return ask(pr,tr[pp].rp,mid+1,R,k-tmp);//左子树不足k个,应该在右子树中找第(k-tmp)小
}
int main(){in(n),in(k); F(1,n)in(a[i]),b[i]=a[i];//复制进b[]并离散去重 sort(b+1,b+n+1);//【离散化】m=unique(b+1,b+n+1)-b-1;//【去重】 F(1,n)pt[i]=creat(pt[i-1],lower_bound(b+1,b+m+1,a[i])-b,1,m);//找出当前这个位置按权值排序后的位置x,进入建树 while(k--)in(x),in(y),in(z),printf("%d\n",ask(pt[x-1],pt[y],1,m,z));//注意是【y】-【x-1】
}

基础题走起:

  • 【模板】可持久化数组(可持久化线段树/平衡树) \([P3919]\)
    【标签】平衡树/线段树/主席树/可持续化

  • \(KUR-Couriers\) \([P3567]\)
    【标签】线段树/主席树/可持续化


八:【可持续化线段树—动态主席树(可修)】

一样的,先上例题: \(Dynamic\) \(Rankings\) \([P2617]\) \([ZOJ2112]\) \([BZOJ1901]\)

【题目大意】

在【静态主席树】的基础上加了一个【单点修改】的操作。

【分析】

回想一下,在刚刚静态线段树中用到了前缀和的思想:对于原数列的每个位置都建立一个权值线段树,用 \(tree[pt[i]]\) 表示从第 \(1\) 个到第 \(i\) 个数这个区间中共 \(i\) 个数所维护成的一棵权值线段树。

它维护的是每个位置前面的一整个大区间,而如果对某个位置 \(i\) 上的数进行了修改,那么从 \(i\) 这个位置开始以后所有的位置上存的信息都要改变(因为位置 \(i\) 后面的所有位置上所存的信息都包含了 \(i\) 的信息)。 那么一次【单点修改】的时间复杂度就是接近于 \(O(nlogn)\) 的,显然不能吗,满足要求。

解决方案:树(树状数组)套树

【树状数组】每一个位置 \(i\) 上的数据 \(C[i]\) 维护的信息是: \(message[i]=\sum_{j=i-lowbit(i)+1}^i message[j]\)

而【静态主席树】每一个位置 \(tree[pt[i]]\) 上的数据 \(C[i]\) 维护的是: \(message[pt[i]]=\sum_{j=1}^i message[pt[j]]\)

【树状数组】:查询 \(O(logn)\),修改 \(O(logn)\)
【静态主席树 \(+\) 暴力】:查询 \(O(logn)\),修改 \(O(nlogn)\)

实际上静态主席树慢就慢在维护的前缀和范围实在是太大了,尤其是最后一个位置,直接就是 \([1\) ~ \(N]\) 的范围。既然如此,为什么不可以把范围缩小一点呢?如果让其维护和树状数组一样的区间,虽然查询第 \(k\) 小上面加了一个 \(O(logn)\),可【单点修改】却降下了一个 \(O(logn)\) ,于是整个问题的时间复杂度就降了下来,可以完美解决了。

【时间复杂度】

每次查询递归 \(logn\) 层,每层最多需要对 \(max(lowbit(i)) \thickapprox logn\) 个节点进行修改,为 \(O(log^2n)\)。

同理,【单点修改】也应该是 \(O(log^2n)\)。

一共 \(Q\) 次操作,为 \(O(Qlog^2n)\)

初始化建树是 \(n\) 次【单点修改】,为 \(nlog^2n\)

总时间复杂度为:\(O((n+Q)log^2n)\)

【空间复杂度】

有 \(Q\) 次操作,如果每次操作都是【单点修改】且每次都是改的一个与之前都不同的数,那么离散化的值域为 \(Q+n\)。

如果要建立完整的第 \(0\) 棵树,会占用 \(n*2\) 个节点,每棵新树的建立都要新建 \(log^2(Q+n)\) 个节点,一共有 \(nlog^2(Q+n)\)。

\(Q\) 次操作,有 \(Qlog^2(Q+n)\)

总空间复杂度:\((Q+n)*log^2(Q+n)\)

数据规模:

\(1 \leqslant N,Q \leqslant 1e5\)

\(200000*21*21*4*3/1024/1024\)

算下来大概是 \(1009MB\),而跑下来实际是大约 \(154.14Mb\)

所以不用慌张,因为实际空间一定是远远小于理论空间的,出题人再怎么良心也不会故意弄一个卡极限的 \(1000Mb\) 数据出来,况且这一类毒瘤题空间限制都大得惊人。

这是洛谷的时空限制:

【Code】

#include<algorithm>
#include<cstring>
#include<cstdio>
#define mid (L+R>>1)
#define Re register int
#define F(i,a,b) for(Re i=a;i<=b;++i)
using namespace std;
const int N=2e5+3;char opt[N];
int x,y,z,n,m,T,t,fu,cnt,tl,tr,a[N],b[N],pt[N],C[N],ptl[20],ptr[20];
//ptl,ptr千万不要开N,否则memset的时候会TLE到怀疑人生
struct QAQ{int g,lp,rp;}tree[N*400];//本应是441左右,开小一点也无所谓,因为根本用不到
struct O_O{int l,r,k;}Q[N];//储存Q次查询的内容,方便离散化
struct T_T{int i,x;}c[N];//离散化数组
inline void in(int &x){x=fu=0;char c=getchar();while(c<'0'||c>'9')fu|=c=='-',c=getchar();while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();x=fu?-x:x;
}
inline int ask_(Re L,Re R,Re k){if(L==R)return b[R];//注意:返回的值需要用到的是哪一个映射数组不能搞错 Re tmp=0;F(i,1,tl)tmp-=tree[tree[ptl[i]].lp].g;//计算左子树信息 F(i,1,tr)tmp+=tree[tree[ptr[i]].lp].g;//计算左子树信息 if(tmp>=k){F(i,1,tl)ptl[i]=tree[ptl[i]].lp;//更新ptl,ptr所指向的节点编号 F(i,1,tr)ptr[i]=tree[ptr[i]].lp;return ask_(L,mid,k);}else{F(i,1,tl)ptl[i]=tree[ptl[i]].rp;F(i,1,tr)ptr[i]=tree[ptr[i]].rp;return ask_(mid+1,R,k-tmp);}
}
inline int ask(Re L,Re R,Re k){//查询第k小 memset(ptl,0,sizeof(ptl));//万恶的memset memset(ptr,0,sizeof(ptr));//数组开太大会疯狂抢时间复杂度 tl=tr=0;for(Re i=L-1;i;i-=i&-i)ptl[++tl]=pt[i];//先把所有要更新的位置的线段树根节点记录下来 for(Re i=R;i;i-=i&-i)ptr[++tr]=pt[i];//方便后面递归更新信息 return ask_(1,m,k);
}
inline void change(Re &p,Re L,Re R,Re w,Re v){if(!p)p=++cnt;tree[p].g+=v;if(L==R)return;if(w<=mid)change(tree[p].lp,L,mid,w,v);else change(tree[p].rp,mid+1,R,w,v);
}
inline void add(Re x,Re v){//【单点修改】Re w=lower_bound(b+1,b+m+1,a[x])-b;//注意函数传进来的参数和这里各种映射数组的调用不要搞错 for(Re i=x;i<=n;i+=i&-i)change(pt[i],1,m,w,v);//树状数组思想更新信息
}
int main(){
//  printf("%lf\n",(sizeof(tree))/1024.0/1024.0);
//  printf("%lf\n",(sizeof(tree)+sizeof(Q)+sizeof(c)+sizeof(a)+sizeof(b)+sizeof(pt)+sizeof(C))/1024.0/1024.0);in(n),in(T),m=n;F(i,1,n)in(a[i]),b[i]=a[i];F(i,1,T){scanf(" %c",&opt[i]);if(opt[i]=='Q')in(Q[i].l),in(Q[i].r),in(Q[i].k);else in(c[i].i),in(c[i].x),b[++m]=c[i].x;}sort(b+1,b+m+1);m=unique(b+1,b+m+1)-b-1;F(i,1,n)add(i,1);//初始化建树 F(i,1,T){if(opt[i]=='Q')printf("%d\n",ask(Q[i].l,Q[i].r,Q[i].k));else add(c[i].i,-1),a[c[i].i]=c[i].x,add(c[i].i,1);
//先让这个位置上原来的数减少一个,再把新数加一个,就达到了替换的目的 }
}

高档题走起:

  • 【模板】二逼平衡树(树套树)\([P3380]\) \([BZOJ3196]\) \([TYVJ1730]\)
    【标签】树套树/平衡树/线段树/树状数组
    【题解】\(Xing\)_\(Ling\)
    (略微有点变态)

转载于:https://www.cnblogs.com/Xing-Ling/p/10886957.html

【学习笔记】线段树详解(全)相关推荐

  1. ELK学习笔记之Logstash详解

    0x00 Logstash概述 官方介绍:Logstash is an open source data collection engine with real-time pipelining cap ...

  2. 线段树详解 (原理,实现与应用)

    线段树详解 By 岩之痕 目录: 一:综述 二:原理 三:递归实现 四:非递归原理 五:非递归实现 六:线段树解题模型 七:扫描线 八:可持久化 (主席树) 九:练习题 一:综述 假设有编号从1到n的 ...

  3. expect学习笔记及实例详解【转】

    1. expect是基于tcl演变而来的,所以很多语法和tcl类似,基本的语法如下所示: 1.1 首行加上/usr/bin/expect 1.2 spawn: 后面加上需要执行的shell命令,比如说 ...

  4. Java中大数据数组,Java基础学习笔记之数组详解

    摘要:这篇Java开发技术栏目下的"Java基础学习笔记之数组详解",介绍的技术点是"java基础学习笔记.基础学习笔记.Java基础.数组详解.学习笔记.Java&qu ...

  5. oracle scn 重置,学习笔记:Oracle SCN详解 SCN与Oracle数据库恢复的关系

    天萃荷净 分享一篇关于Oracle SCN的详解,介绍SCN与Oracle数据库恢复的关系和SCN在数据库中的作用 一.为什么需要System checkpoint SCN号与Datafile Che ...

  6. 【Python全栈100天学习笔记】Day37MySQL详解(sql语句基本操作含索引、视图、存储过程)

    SQL详解 基本操作 我们通常可以将SQL分为三类:DDL(数据定义语言).DML(数据操作语言)和DCL(数据控制语言).DDL主要用于创建(create).删除(drop).修改(alter)数据 ...

  7. 如何在vs中创建r树索引代码_线段树详解与实现

    此篇文章用于记录<玩转数据结构>课程的学习笔记 什么是线段树 线段树也被称为区间树,英文名为Segment Tree或者Interval tree,是一种高级的数据结构.这种数据结构更多出 ...

  8. shell入门学习笔记-12-命令详解: echo与printf

    系列目录与参考文献传送门: shell入门学习笔记-序章 命令详解 admindeMacBook-Pro:myshell admin$ type cd cd is a shell builtin ad ...

  9. PyQt5学习笔记——一文详解QObject

    QObject详解笔记1 一.简介 QObject是所有Qt对象的基类 二.功能作用 2.1 对象名称.属性 2.1.1 API setObjectName("唯一名称") 给QT ...

最新文章

  1. java基础 多维数组_java基础:3.2 多维数组
  2. [示例]创建Student类,输入学生信息并存入字典,将3个存有学生信息的字典存入数组,并计算...
  3. 一个关于hashCode的追问!
  4. android 直播 app下载地址,蓝泡泡直播
  5. python k线图 动态刷新不了_ImageButton点击之后不动态刷新页面的解决方案
  6. KVO 实现两个页面之间的通信
  7. (转)SpringMVC学习(十)——SpringMVC与前台的json数据交互
  8. 绿地深蓝机器人_人工智能企业深兰科技获绿地控股3亿元战略投资
  9. atomic与nonatomic的区别
  10. mysql 存储过程创建表_MySQL之存储过程按月创建表的方法步骤
  11. Redis 持久化 RDB 详解
  12. centos7连接华为san存储_centos7配置nfs共享存储服务
  13. 学习动态性能表3----v$session_wait
  14. 【Java 集合框架】最全的 Java 集合框架入门手册
  15. 爆破神器 Hydra 的使用
  16. cdrom是多媒体微型计算机,2011年计算机一级考试理论试题:多媒体
  17. html5画直线箭头,HTML5 canvas画带箭头的虚线
  18. Excel.Application使用手册(API)
  19. Day17 什么是静态成员类?为什么静态成员类优于非静态成员类?
  20. TikTok视频没播放,涨粉难?狠抓5点,TikTok运营so easy!

热门文章

  1. java makefile jar包_makefile PRODUCT_BOOT_JARS 处理流程及实例
  2. 清理 Anaconda 的 pkgs
  3. 诡异!意识何以意识到意识自身?道翰天琼认知智能机器人API接口平台为您揭秘。
  4. Teams App自定义
  5. m4a转mp3方法,m4a转mp3步骤
  6. 眼底图像血管增强与分割--(5)基于Hessian矩阵的Frangi滤波算法
  7. ios 七种手势详解
  8. java编写一个可切换的界面_java web 项目实现手动中英文切换
  9. Java 习题 (12)
  10. 13 个非常有用的 Python 代码片段,建议收藏