这是两个月前写的,看能不能搬运过来……

动态树是一类维护森林连通性的问题(已纠正,感谢ZQC巨佬),目前最(wo)常(zhi)见(hui)的动态树就是LCT(Link-Cut-Tree),然而LCT似乎是处理路径的,处理子树可能力不足。据说有一种称为Top Tree数据结构,可以处理所有。但是学不动了Orz
LCT中最主要的是Access操作,Access(u)操作的含义是,从当前的节点u向他所在的根节点连一条重路径,这是相当于把沿路的重路径全都断开,重新拉一条从u到根的重路径。
makeroot(x)操作:
若想让u成为当前树的根节点,则可以先access(u),再splay(u),把u转为当前splay的根节点。因为splay维护的是深度,所以u没有右儿子(没有比u还要深的点,因为重链定义),所以换根就相当于一次区间翻转,交换左右子树即完成区间翻转。此时就可以打标记了。
所以,makeroot=access+splay+rev
还有一个isroot操作,超级简单,就是判断这是不是一条重路径的根,只要他的fa指针指向的节点的左右子树都不是他(证明此时这是一条虚边),那么这就是一棵子树的根节点。
link(x,y)操作:
在u和v之间连边,可以makeroot(u),再让u的父亲为v,这就相当于v本身是一棵splay,而u和v之间连了条轻边。
cut(u,v)操作:
断开u和v之间的边,可以先makeroot(u),再access(v),再splay(v),此时v的左儿子必定为u,于是断开v和v的左儿子即可。
至于翻转标记的传递,就是跟Splay一样就行了。
但标记下放有一个问题。因为splay是时时刻刻在分裂与合并的,因为要动态维护每条重链,所以在splay之前,要先把根节点到当前节点全部下放一遍标记,防止标记下放不完全。
split(x,y)操作:
split相当于把两个子树分开,考虑到我们cut的时候第一步也是分开,所以

$split=makeroot(u)+access(v)+splay(v)$
然后还要保存一些轻边(虚边),对于轻边我们需要单独记录处理。在原树上,当前重链的顶端节点与他的父亲的边即为轻边,如果不记录,树将是不完整的。
具体到代码实现,可以是当前splay的根节点的父亲即为当前splay上面的那个重链所在的splay上的点,但上面的splay的儿子并不指向当前splay的父亲,即为用splay的根节点的父亲来存储轻边。
动态树的主要时间消耗在Access上,而Access的时间复杂度是

$O(nlogn)$
好像最后在UOJ群里看到一句话:
*树剖能做的,动态树都能做,只不过有的东西动态树做起来比树剖烦的多*
好像超级有道理,因为我写的维护子树size,树剖的话天生自带,但是LCT每次Access跳轻重边的时候都要交换,超级烦。
下面是这几天做的一点题目:
1.洞穴勘测
裸的连通性询问。

 #include<bits/stdc++.h>
#define N 10005
#define inf 1000000007
using namespace std;
int n,m;
struct Link_Cut_Tree{
int fa[N],c[N][],q[N],top;bool rev[N];
Link_Cut_Tree(){
top=;memset(fa,,sizeof(fa));
memset(c,,sizeof(c));
memset(rev,,sizeof(rev));
}
inline bool isroot(int x){return c[fa[x]][]!=x&&c[fa[x]][]!=x;}
inline void pushdown(int x){
int l=c[x][],r=c[x][];
if(rev[x]){
rev[x]^=;rev[l]^=;rev[r]^=;
swap(c[x][],c[x][]);
}
}
void rotate(int x){
int y=fa[x],z=fa[y],l,r;
l=(c[y][]==x);r=l^;
if(!isroot(y))c[z][c[z][]==y]=x;
fa[c[x][r]]=y;fa[y]=x;fa[x]=z;
c[y][l]=c[x][r];c[x][r]=y;
}
void splay(int x){
int top=;q[++top]=x;
for(int i=x;!isroot(i);i=fa[i])q[++top]=fa[i];
while(top)pushdown(q[top--]);
while(!isroot(x)){
int y=fa[x],z=fa[y];
if(!isroot(y)){
if(c[y][]==x^c[z][]==y)rotate(x);else rotate(y);
}
rotate(x);
}
}
void access(int x){for(int t=;x;t=x,x=fa[x])splay(x),c[x][]=t;}
void makeroot(int x){access(x);splay(x);rev[x]^=;}
void link(int x,int y){makeroot(x);fa[x]=y;splay(x);}
void split(int x,int y){makeroot(x);access(y);splay(y);}
void cut(int x,int y){split(x,y);c[y][]=fa[x]=;}
int find(int x){
access(x);splay(x);int y=x;while(c[y][])y=c[y][];return y;
}
}T;
inline int read(){
int x=,f=;char ch;
do{ch=getchar();if(ch=='-')f=-;}while(ch<''||ch>'');
do{x=x*+ch-'';ch=getchar();}while(ch>=''&&ch<='');
return f*x;
}
int main(){
char s[];int x,y;
n=read();m=read();
for(int i=;i<=m;i++){
scanf("%s",s);
x=read();y=read();
if(s[]=='C')T.link(x,y);
if(s[]=='D')T.cut(x,y);
if(s[]=='Q'){
int xx=T.find(x),yy=T.find(y);
if(xx==yy)puts("Yes");else puts("No");
}
}
return ;
}

2.bzoj1180 OTOCI
修改,连边,区间权值合。
其实可以先读入所有的边得到最后的树,然后离线树剖,用并查集维护边就行了
本蒟蒻还是写了Link-Cut-Tree

 #include<bits/stdc++.h>
#define N 30005
#define inf 1000000000
#define yql 1000000007
#define ll long long
using namespace std;
int q,n;
struct Link_Cut_Tree{
int c[N][],fa[N],sumv[N],val[N],q[N],top[N];
bool rev[N];
void pushup(int x){
int l=c[x][],r=c[x][];sumv[x]=sumv[l]+sumv[r]+val[x];
}
void pushdown(int x){
int l=c[x][],r=c[x][];
if(rev[x]){
rev[x]^=;rev[r]^=;rev[l]^=;
swap(c[x][],c[x][]);
}
}
bool isroot(int x){return c[fa[x]][]!=x&&c[fa[x]][]!=x;}
void rotate(int x){
int y=fa[x],z=fa[y],l,r;
l=(c[y][]==x);r=l^;
if(!isroot(y))c[z][c[z][]==y]=x;
fa[c[x][r]]=y;fa[y]=x;fa[x]=z;
c[y][l]=c[x][r];c[x][r]=y;
pushup(y);pushup(x);
}
void splay(int x){
int top=;q[++top]=x;
for(int i=x;!isroot(i);i=fa[i])q[++top]=fa[i];
while(top)pushdown(q[top--]);
while(!isroot(x)){
int y=fa[x],z=fa[y];
if(!isroot(y)){
if(c[y][]==x^c[z][]==y)rotate(x);else rotate(y);
}
rotate(x);
}
}
void access(int x){for(int t=;x;t=x,x=fa[x])splay(x),c[x][]=t,pushup(x);}
void makeroot(int x){access(x);splay(x);rev[x]^=;}
void link(int x,int y){makeroot(x);fa[x]=y;}
void split(int x,int y){makeroot(x);access(y);splay(y);}
void cut(int x,int y){split(x,y);c[y][]=fa[x]=;}
int find(int x){
access(x);splay(x);int y=x;while(c[y][])y=c[y][];return y;
}
}T;
inline int read(){
int f=,x=;char ch;
do{ch=getchar();if(ch=='-')f=-;}while(ch<''||ch>'');
do{x=x*+ch-'';ch=getchar();}while(ch>=''&&ch<='');
return f*x;
}
int main(){
n=read();
for(int i=;i<=n;i++){T.sumv[i]=read();T.val[i]=T.sumv[i];}
q=read();char s[];
while(q--){
scanf("%s",s);int x=read(),y=read();
if(s[]=='b'){
int xx=T.find(x),yy=T.find(y);
if(xx==yy)puts("no");
else puts("yes"),T.link(x,y);
}
if(s[]=='p')T.makeroot(x),T.val[x]=y,T.pushup(x);
if(s[]=='e'){
int xx=T.find(x),yy=T.find(y);
if(xx!=yy)puts("impossible");
else{
T.makeroot(x);T.access(y);T.splay(y);
printf("%d\n",T.sumv[y]);
}
}
}
return ;
}

3.NOI2014 膜法森林
考虑Kruskal求出最小生成树,每次加,如果当前的边成环,那么就在之前的边里找一个最大权的cut掉。
维护连通性,cut边,最大值询问,LCT很擅长啦~

 #include<bits/stdc++.h>
#define inf 1000000007
#define N 200005
using namespace std;
int n,m,cnt,_=inf;
int f[N];
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
struct Edge{
int u,v,w,c;
bool operator<(const Edge &x)const{return w<x.w;}
}G[*N]; struct Link_Cut_Tree{
int c[N][],fa[N],q[N],rev[N],top;
int maxv[N],val[N];
inline void pushup(int x){
int l=c[x][],r=c[x][];
maxv[x]=x;
if(val[maxv[l]]>val[maxv[x]])maxv[x]=maxv[l];
if(val[maxv[r]]>val[maxv[x]])maxv[x]=maxv[r];
}
Link_Cut_Tree(){top=;memset(rev,,sizeof(rev));}
bool isroot(int x){return c[fa[x]][]!=x&&c[fa[x]][]!=x;}
void pushdown(int x){
int l=c[x][],r=c[x][];
if(rev[x]){
rev[l]^=;rev[r]^=;rev[x]^=;
swap(c[x][],c[x][]);
}
}
void rotate(int x){
int y=fa[x],z=fa[y],l,r;
l=(c[y][])==x;r=l^;
if(!isroot(y))c[z][c[z][]==y]=x;
fa[c[x][r]]=y;fa[y]=x;fa[x]=z;
c[y][l]=c[x][r];c[x][r]=y;
pushup(y);pushup(x);
}
void splay(int x){
int top=;q[++top]=x;
for(int i=x;!isroot(i);i=fa[i])q[++top]=fa[i];
while(top)pushdown(q[top--]);
while(!isroot(x)){
int y=fa[x],z=fa[y];
if(!isroot(y)){
if(c[y][]==x^c[z][]==y)rotate(x);else rotate(y);
}
rotate(x);
}
}
void access(int x){for(int t=;x;t=x,x=fa[x])splay(x),c[x][]=t,pushup(x);}
void makeroot(int x){access(x);splay(x);rev[x]^=;}
void link(int x,int y){makeroot(x);fa[x]=y;splay(x);}
void split(int x,int y){makeroot(x);access(y);splay(y);}
void cut(int x,int y){split(x,y);c[y][]=fa[x]=;pushup(y);}
int find(int x){access(x);splay(x);int y=x;while(c[y][])y=c[y][];return y;}
int querymax(int x,int y){split(x,y);return maxv[y];}
};
Link_Cut_Tree T;
inline int read(){
int f=,x=;char ch;
do{ch=getchar();if(ch=='')f=-;}while(ch<''||ch>'');
do{x=x*+ch-'';ch=getchar();}while(ch>=''&&ch<='');
return f*x;
}
int main(){
n=read();m=read();
for(int i=;i<=n+;i++)f[i]=i;
for(int i=;i<=m;i++){
G[i].u=read(),G[i].v=read(),G[i].w=read();G[i].c=read();
}
sort(G+,G+m+);
int tot=;
for(int i=;i<=m;i++){
int u=G[i].u,v=G[i].v,w=G[i].w,c=G[i].c;
if(find(u)==find(v)){
int t=T.querymax(u,v);
if(T.val[t]>G[i].c){
T.cut(t,G[t-n].u);
T.cut(t,G[t-n].v);
}
else {
if(find()==find(n))_=min(_,G[i].w+T.val[T.querymax(,n)]);
continue;
}
}
else f[find(u)]=find(v);
T.val[n+i]=G[i].c;T.maxv[n+i]=n+i;
T.link(u,n+i);T.link(v,n+i);
if(find()==find(n))_=min(_,G[i].w+T.val[T.querymax(,n)]);
}
if(_==inf)puts("-1");else printf("%d\n",_);
return ;
}

4.uoj 共价大爷游长沙
%%%%毛爷爷,不看题解不会系列。
这题做的极其艰辛:
1.zcy:我怎么维护子树size啊…………啊………………
想了半个下午,我好像会了!去机房写!
2.zcy:我的权值怎么这么小啊,都是几十几十的东西……
wori,随机数种子选的有毒?我去uoj上找一个吧……
3.zcy:我的link怎么权值改的那么鬼啊?我看看……
wori,cut写错了,mdzz。
代码准确度啊……

#include<bits/stdc++.h>
#define N 300100
using namespace std;
int n,m,x,y,z;
struct Link_Cut_Tree{
int c[N][],q[N],fa[N],size[N],top,rev[N],val[N],sumv[N];
int a[N],b[N],w[N],sum;
inline bool isroot(int x){return fa[x]==||c[fa[x]][]!=x&&c[fa[x]][]!=x;}
inline void pushdown(int x){
int l=c[x][],r=c[x][];
if(rev[x]){
rev[l]^=;rev[r]^=;rev[x]^=;
swap(c[x][],c[x][]);
}
}
void pushall(int x){
if(!isroot(x))pushall(fa[x]);pushdown(x);
}
inline void pushup(int x){
sumv[x] = val[x]^sumv[c[x][]]^sumv[c[x][]];
}
void rotate(int x){
int y = fa[x],g=fa[y],ch=c[y][]==x;
if (!isroot(y))c[g][c[g][]==y]=x;
c[y][ch]=c[x][!ch],fa[c[y][ch]]=y;
fa[y] =x,fa[x]=g,c[x][!ch] = y;
pushup(y);
}
void splay(int x){
int top=;q[++top]=x;
for(int i=x;!isroot(i);i=fa[i])q[++top]=fa[i];
while(top)pushdown(q[top--]);
while(!isroot(x)){
int y=fa[x],z=fa[y];
if(!isroot(y)){
if(c[y][]==x^c[z][]==y)rotate(x);else rotate(y);
}
rotate(x);
}
pushup(x);
}
void access(int x){
for(int t=;x;t=x,x=fa[x]){
splay(x);val[x]^=sumv[t]^sumv[c[x][]];
c[x][]=t;pushup(x);
}
}
void makeroot(int x){access(x);splay(x);rev[x]^=;}
void link(int x,int y){
makeroot(x);makeroot(y);fa[x]=y;val[y]^=sumv[x];pushup(y);
}
void split(int x,int y){makeroot(x);access(y);splay(y);}
void cut(int x,int y){
makeroot(y);access(y);splay(x);fa[x]=;val[y]^=sumv[x];pushup(y);
}
void change(int x,int v){access(x);splay(x);val[x]^=v;pushup(x);}
}T; struct Edge{
int u;int v;int w;
Edge(int a=,int b=,int c=){u=a;v=b;w=c;}
}G[*N];
inline int read(){
int x=,f=;char ch;
do{ch=getchar();if(ch=='-')f=-;}while(ch<''||ch>'');
do{x=x*+ch-'';ch=getchar();}while(ch>=''&&ch<='');
return f*x;
}
int main(){
int id;
id=read();n=read();m=read();
srand(time(NULL));
for(int i=;i<n;i++){
x=read(),y=read();
T.link(x,y);
}x=;y=;
int tot=,res=;
while(m--){
int opt=read(),x,y,u,v;
if(opt==){
x=read();y=read();u=read();v=read();
T.cut(x,y);T.link(u,v);//printf("%d\n",T.val[v]);
}
else if(opt==){
int k=rand();
x=read(),y=read();while(!k)k=rand();
G[++tot]=Edge(x,y,k);res^=k;
T.change(x,k);T.change(y,k);
//printf("%d\n",T.val[y]);
}
else if(opt==){
x=read();
res^=G[x].w;
T.change(G[x].u,G[x].w);T.change(G[x].v,G[x].w);
}
else if(opt==){
x=read();y=read();
T.makeroot(x);T.access(y);
if(T.val[y]==res)puts("YES");
else puts("NO");
}
//printf("%d\n",res);printf("%d\n",T.val[y]);
}
return ;
}

不开心,这个快把我写死的LCT居然只有100行
5.ZJOI2012 网络
这题如果单看每种颜色,我们只要建一个LCT就能轻松水过去,无非是要加个cnt
但是颜色多怎么办?考虑颜色种类很小,我们多建几个LCT不就行了么?

 #include<bits/stdc++.h>
#define N 10005
#define M 100005
using namespace std;
int n, m, c, k, u, v, w, op, x,val[N];
struct Link_Cut_Tree{
int c[N][],fa[N],rev[N],maxv[N],cnt[N],q[N];
inline void pushup(int x){
maxv[x]=val[x];int l=c[x][],r=c[x][];
if(l)maxv[x]=max(maxv[x],maxv[l]);
if(r)maxv[x]=max(maxv[x],maxv[r]);
}
inline void pushdown(int x){
int l=c[x][],r=c[x][];
if(rev[x]){
rev[l]^=;rev[r]^=;rev[x]^=;
swap(c[x][],c[x][]);
}
}
bool isroot(int x){return c[fa[x]][]!=x&&c[fa[x]][]!=x;}
void rotate(int x){
int y=fa[x],z=fa[y],l,r;
l=(c[y][])==x;r=l^;
if(!isroot(y))c[z][c[z][]==y]=x;
fa[c[x][r]]=y;fa[y]=x;fa[x]=z;
c[y][l]=c[x][r];c[x][r]=y;
pushup(y);pushup(x);
}
void splay(int x){
int top=;q[++top]=x;
for(int i=x;!isroot(i);i=fa[i])q[++top]=fa[i];
while(top)pushdown(q[top--]);
while(!isroot(x)){
int y=fa[x],z=fa[y];
if(!isroot(y)){
if(c[y][]==x^c[z][]==y)rotate(x);else rotate(y);
}
rotate(x);
}
}
void access(int x){for(int t=;x;t=x,x=fa[x])splay(x),c[x][]=t,pushup(x);}
void makeroot(int x){access(x);splay(x);rev[x]^=;}
void link(int x,int y){cnt[x]++;cnt[y]++;makeroot(x);fa[x]=y;splay(x);}
void split(int x,int y){makeroot(x);access(y);splay(y);}
void cut(int x,int y){split(x,y);cnt[x]--;cnt[y]--;c[y][]=fa[x]=;pushup(y);}
int find(int x){access(x);splay(x);int y=x;while(c[y][])y=c[y][];return y;}
int querymax(int x,int y){split(x,y);return maxv[y];}
}lct[];
inline int read(){
int f=,x=;char ch;
do{ch=getchar();if(ch=='')f=-;}while(ch<''||ch>'');
do{x=x*+ch-'';ch=getchar();}while(ch>=''&&ch<='');
return f*x;
}
struct Edge{
int u,v;
bool operator<(const Edge &x)const{if(u!=x.u)return u<x.u;
else return v<x.v;}
};
map<Edge,int> mp;
int main(){
n=read();m=read();c=read();k=read();
for(int i=;i<=n;i++)val[i]=read();
for(int i=;i<=m;i++){
int u=read(),v=read(),w=read();
w++;
Edge e1=(Edge){u,v},e2=(Edge){v,u};
mp[e1]=mp[e2]=w;
lct[w].link(u,v);
}
while(k--){
int opt=read();
if(opt==){
int x=read(),w=read();
val[x]=w;
for(int i=;i<=c;i++)lct[i].splay(x);
}
else if(opt==){
int u=read(),v=read(),w=read();
w++;
Edge a=(Edge){u,v},b=(Edge){v,u};
if(!mp.count(a)){
puts("No such edge.");continue;
}
int xxx=mp[a];
if(xxx==w){
puts("Success.");continue;
}
if(lct[w].cnt[u]>=||lct[w].cnt[v]>=){
puts("Error 1.");continue;
}
if(lct[w].find(u)==lct[w].find(v)){
puts("Error 2.");continue;
}
puts("Success.");
lct[xxx].cut(u,v);lct[w].link(u,v);
mp[a]=mp[b]=w;
}else{
int w=read(),u=read(),v=read();
w++;
if(lct[w].find(u)!=lct[w].find(v)){
puts("-1");continue;
}
printf("%d\n",lct[w].querymax(u,v));
}
}
return ;
}

【学习笔记】动态树Link-Cut-Tree的更多相关文章

  1. 动态树(Link Cut Tree) :SPOJ 375 Query on a tree

    QTREE - Query on a tree #number-theory You are given a tree (an acyclic undirected connected graph) ...

  2. 【学习笔记】LCT link cut tree

    大概就是供自己复习的吧 1. 细节讲解 安利两篇blog: Menci 非常好的讲解与题单 2.模板 把 $ rev $ 和 $ pushdown $ 的位置记清 #define lc son[x][ ...

  3. 学习笔记-动态树Link-Cut-Tree

    --少年你有梦想吗? --少年你听说过安利吗? 安利一个集训队讲解:http://wenku.baidu.com/view/75906f160b4e767f5acfcedb 关于动态树问题,有多种方法 ...

  4. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

  5. Link Cut Tree学习笔记

    从这里开始 动态树问题和Link Cut Tree 一些定义 access操作 换根操作 link和cut操作 时间复杂度证明 Link Cut Tree维护链上信息 Link Cut Tree维护子 ...

  6. P3690 【模板】Link Cut Tree (动态树)

    P3690 [模板]Link Cut Tree (动态树) 认父不认子的lct 注意:不 要 把 $fa[x]$和$nrt(x)$ 混 在 一 起 ! #include<cstdio> v ...

  7. 【刷题】洛谷 P3690 【模板】Link Cut Tree (动态树)

    题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor ...

  8. LuoguP3690 【模板】Link Cut Tree (动态树) LCT模板

    P3690 [模板]Link Cut Tree (动态树) 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两 ...

  9. 学习笔记:Link Cut Tree

    模板题 原理 类似树链剖分对重儿子/长儿子剖分,Link Cut Tree 也做的是类似的链剖分. 每个节点选出 \(0 / 1\) 个儿子作为实儿子,剩下是虚儿子.对应的边是实边/虚边,虚实时可以进 ...

  10. LG3690 【模板】Link Cut Tree (动态树)

    题意 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联通的 ...

随机推荐

  1. 编译 python 生成静态库 libpython2.7.so

    由于我们是C++作驱动的Python开发,驱动需要加上Python静态库libpython2.7.so.libpython2.7.so.1.0.libpython2.7.a.此处我想在python源码 ...

  2. P1667 数列

    题目描述 给定一个长度是n的数列A,我们称一个数列是完美的,当且仅当对于其任意连续子序列的和都是正的.现在你有一个操作可以改变数列,选择一个区间[X,Y]满足Ax +Ax+1 +…+ AY<0, ...

  3. CentOS ACL

    ACL:访问控制列表(Access Control List). 一般来说权限是针对某一类用户设置的.例如:一个文件只有拥有者.组.其他用户三种设置方式,如果希望对某个指定的用户进行单独的权限控制,就 ...

  4. springboot2.0 集成elasticsearch,实现检索、分页、排序

    springboot整合es的方式: transport方式(7.0弃用,8.0移除) spring-data(完全当做数据库来用,无法全部支持es,内部也是基于transport,包装后使用非常简单 ...

  5. [HNOI2008]GT考试 矩阵优化DP

    ---题面--- 题解: 一开始看觉得很难,理解了之后其实还挺容易的. 首先我们考虑朴素DP: 令f[i][j]表示长串到了第i项, 与不吉利数字(模式串)匹配到了第j项的方案. 显然ans = f[ ...

  6. input file上传图片预览,非插件

    Input标签 <input type="file" name="pic" onchange="changepic(this)" mu ...

  7. windows下安装git

    1.从Git官网下载windows版本的git:http://git-scm.com/downloads 2.一般使用默认设置即可:一路next,git安装完毕! 3.但是如果这时你打开windows ...

  8. HDU 3277 最大流+二分

    Marriage Match III Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  9. ELK6.0环境搭建及配置

    ELK环境搭建及配置 ElasticSearch在5.x后的安装和插件的官方执行更好了,head插件官方默认集成在kibana的dev tools里,支持rpm包方式安装,x-pack安装后支持权限及 ...

  10. 【C++对象模型】第二章 构造函数语意学

    1.Default Constructor 当编译器需要的时候,default constructor会被合成出来,只执行编译器所需要的任务(将members适当初始化). 1.1  带有 Defau ...