【用皇宫三十六计生存法则带你走进LCT(动态树)】LCT概念+模板+例题【洛谷P3690 Link Cut Tree(动态树)】

文章目录

  • LCT概念
  • 模板
    • rotato
    • isroot
    • splay
    • access
    • makeroot
    • split
    • findroot
    • link
    • cut
    • 封装版
  • 例题
    • 题目
    • code普通版
    • code封装版

在这里插入图片描述
这篇博客主要是帮助大家理解各个模板及LCTLCTLCT的意思,方便理解,模板写法的理解在代码里有注释详解,如果要看原理的话,有很多写得好的博客,我就不跟着大众的步伐前进了,咱们要另辟蹊径
写完后发现皇宫其实就是皇帝和太子的乱来,而且太子妃好像还是另外国家的皇帝或者皇帝继承人
那不都是男的。。。

LCT概念

等价映射
事实上, 所有解决动态树问题的方法, 归根结底都使用等价映射的基本思想
即, 将任意形态的树(原树)映射到度限制, 深度平均的新树(辅助树)上.
Link-Cut Tree是由Sleator、Tarjan等科学家提出的一种实现动态树的数据结构


接下来皇宫生存法则开始啦(≧▽≦)/(为了方便大家区分,以下的这种文字都是表示皇宫三十六计生存法则的理解带入

Link-Cut Tree的若干概念
原树(represented trees):是若干有根树组成的森林,每棵树与标准的有根树无异,只不过增加了一个“优先(preference)”的概念

也就是一个大背景的前提,在这个辉煌的皇宫内部,最初始的树的根我们理解为皇帝

一个结点可能“偏好(prefer)”某个儿子,使它成为“优先儿子(preferred child)” 皇室继承者太子
不得不说真的是一个昏君啊,不用贤明的儿子却用偏心的儿子当太子
类似于树链剖分中的“重儿子”
优先儿子与它父亲之间的边称为“优先边(preferred edge)” 有什么好处皇帝都先考虑自己宠爱的儿子
类似于“重边”仅由优先边组成的路径称为“优先路径(preferredpath)” 太子只能有一个也就只能宠爱一个
类似于“重链”优先路径有可能只有一个结点被宠爱的子孙后代构成的庞大家族体系

在这里插入图片描述

需要注意的是,用树链剖分的对应概念来类比,只是帮助大家尽快理解Link-Cut Tree中引入的新概念
两者的区别是显著的:重儿子、重边、重链等是静态的,而优先关系是动态的,随时可能变化
但是皇宫法则是动态变换的,说不定哪一天你就被打入冷宫,甚至国都灭亡了


通常,我们遇到的问题都是在原树上的
那些吃了雄心豹子胆的人,生怕皇帝忘了还有他们的存在,在皇帝眼皮子底下乱来,甚至敢分裂出不同王朝
因此,我们首先搞清楚在原树上要执行的是什么特定操作,然后解释这个操作在Link-Cut Tree上怎样执行

Link-Cut Tree定义如下:
路径树(path tree )是用来表示原树上的优先路径的树。路径树用splay tree实现你可以把一棵splay理解为一个王朝,结点是原树的一条优先路径上所有结点,并以结点在原树上的深度为关键字
为了解决这个庞大的家族体系,因为皇帝说不定会忘记自己生了那么多儿子,宠了那么多妃子,但是他必须要让整个皇宫都在他的掌握范围内,这个时候大臣就特别贴心的帮他理了一份家族关系,而且深入研究发现各个之间的亲密程度,一五一十都汇报给了皇帝,他也不恼任着子孙们乱来,只要别把国搞没了就行,是啊~自己都被子孙挤下去了,国也分散了

路径树也叫辅助树(Auxiliary Tree)大王朝在昏君的执政下,成功解体
Link-Cut tree的核心思想是把原树剖分成若干优先路径,然后把每条优先路径用一棵对应的路径树表示
每一个相互亲近的人成为一个团体,彼此互帮互助,也因为彼此之间的不团结,将大王朝分成了多个王朝,产生了多个不同的皇帝,更绝的是彼此之间互不干涉永不往来,留一条丝表示还有血缘关系,哪天心情一好就把对方吞并了

准确地说,原树剖分后是一组辅助树森林。多个王朝,每一个王朝都有一个能力强的皇帝,形成了各自的皇宫,用着统一的皇宫规则
在这里插入图片描述
每棵路径树的根结点v对应王朝的皇帝都有一个“路径-父亲(path-parent)”指针,指向原树上对应优先路径中最高结点的父结点u它的父亲有可能在另一个王朝是最低等/中等/皇帝的地位。但u的儿子指针并不指向v他的父亲可能忘记了自己儿子是另外一个王朝的皇帝,还是宠信着跟自己在同一个王朝的唯一儿子(利用这一性质,可以省略path-parent指针,也是认父不认子)儿子认着自己的父亲想讨好自己的父亲让自己跟父亲在同一个王朝放着自己的皇位不坐你搞peach吗??还真是孝顺呢!
每个人都有自己想讨好的对象,而且吊死在一棵树上,但是被讨好的人也十分嚣张跋扈,不稀罕


原树与辅助树的关系
箭头的有向边表示path-parent指针
在这里插入图片描述
一个复杂的例子皇宫家族分裂王朝体系
在这里插入图片描述
左图是原树,红边表示优先路径每个爸爸宠幸的一个儿子
右图是辅助树。虚线表示path-parent指针
注意,右图的单个结点也是一棵辅助树

对于一个 splaysplaysplay 而言,按照中序遍历,在原树上先遍历的是后遍历的祖先。
看似二叉实际上在原树上每个 splaysplaysplay 都是一条链。

原树中的重链 -> 辅助树中结点们位于同一棵Splay中 尽管可能自己孤家寡人一个,也可以建立只有一个人的空王朝,然后去吞并其它王朝嘛!
原树中的轻边 -> 辅助树中子结点所在Splay的根节点的pathparent指向父结点
原树与辅助树的结构并不相同。原树是多叉的,而辅助树是二叉排序树。
辅助树的根节点 ≠ 原树的根节点
辅助树中的path-parent ≠ 原树中的fa

由于要维护的信息已经都在辅助树中维护了,所以LCT无需维护原树,只维护辅助树即可.
原树已经被拆解成一条一条的重链,表达成一组辅助树森林。
轻边和重链并不是固定的,随着算法的进行,轻链和重链随算法需要和题目要求而变化,然而无论怎么变化,由这棵辅助树一定能生成原树,并满足辅助树的所有性质.


如果你懵了,不用担心这很正常,而且前面的废话也没有多少用,你直接跳过都行,只要把模板整好了
你就已经很可以了
但是你至少要知道,虚边是一棵splaysplaysplay的根连出去,连到另一个splaysplaysplay里面的某一点
一条条虚边把王朝牵扯到了一起,方便自己想吞并其它王朝时自己方便和被吞并时对方方便,聪明啊!!

模板


rotato

旋转操作,我将其亲切地尊称为在自己的王朝里面合理地篡位,可能是争夺当太监,当宠妃...争夺当皇帝,我的天胆子挺大啊!

void rotate ( int x ) { int fa = tree[x].f; int Gfa = tree[fa].f;int k = ( tree[fa].son[1] == x );if ( isroot ( fa ) )//因为虚边是一棵splay的根连出去 剩下的自己内部交换是无影响的 所以一定要判断 tree[Gfa].son[tree[Gfa].son[1] == fa] = x;tree[x].f = Gfa; tree[fa].son[k] = tree[x].son[k ^ 1];if ( tree[x].son[k ^ 1] )tree[tree[x].son[k ^ 1]].f = fa;tree[x].son[k ^ 1] = fa;tree[fa].f = x;update ( fa );update ( x );
}

isroot

判断是否为根,其名曰在你所在的王朝里面,看你是不是穿着黄袍的皇上

bool isroot ( int x ) {//判断x是否为splay的根 return tree[tree[x].f].son[0] == x || tree[tree[x].f].son[1] == x;
}//如果连的是虚边那么它的父亲的儿子里面就没有它 

splay

将点变成splay的根可以说是和rotate一起帮助它篡位成功的宦官心腹,一路上绝杀成为皇帝,该王朝要变天啦!

void splay ( int x ) {//所有操作的目标都是该splay的根int Top = 0, y = x;st[++ Top] = y;//手打栈暂存当前点到根的整条路径 pushdown时要从上往下放标记while ( isroot ( y ) )st[++ Top] = y = tree[y].f;while ( Top )pushdown ( st[Top -- ] );while ( isroot ( x ) ) {int fa = tree[x].f, Gfa = tree[fa].f;if ( isroot ( fa ) )( ( tree[Gfa].son[0] == fa ) ^ ( tree[fa].son[0] == x ) ) ? rotate ( x ) : rotate ( fa );rotate ( x );}
}

access

将x与根打通,使之同在一个splay
叫做争夺嫡系皇位继承人 成为最小的已经确定的皇位继承人,把自己的兄弟挤出去,且它很贪心,子孙后代都还没确定选谁做自己的继承人,想多当一会皇帝继承人,当然这是不可能,很快就被挤下去了。我实在不能理解为什么这个人不直接篡位当皇帝,非要把一路上的亲戚都买通一起当皇位继承人


接着盗一波图,实在画得太好了
在这里插入图片描述
绿色的表示一个splaysplaysplay,这个LCTLCTLCT不是唯一的,也有其他划分方案
在这里插入图片描述
我们要打通A−NA-NAN每个爸爸宠信的儿子都可能会发生改变,王朝里的成员随时都在发生着改变,进行着吞并和分裂
在这里插入图片描述
篡位要一步一步来,先让N成为他们小王朝的皇帝
在这里插入图片描述
接着跟自己的爸爸搞好关系,以表尊重把自己的王朝都一起搭了进去当做嫁妆用花言巧语哄骗他宠爱自己,成为他的第一继承人我怎么感觉像是妃子争宠而不是儿子争位呢??
在这里插入图片描述
用自己的爸爸去哄骗自己的爷爷,这样爸爸当了第一继承人自己也会获得此王朝皇位的继承权了你为啥不直接冲上去啊,搞啥子地下情
在这里插入图片描述
最后不知不觉间跟皇帝成了一个王朝的人,还帮皇帝吞并其它王朝分裂势力,给皇帝都搞懵了,它还是很聪明的,在最下面操作着一切,一家族都跟着篡位,而不是他一个人单枪匹马闯上去,不仅会让皇帝无语而且也不会让自己的家族势力眼红,因为他们都是第一继承人,实在是妙啊!!!
在这里插入图片描述

void access ( int x ) {for ( int son = 0;x;son = x, x = tree[x].f ) {splay ( x );tree[x].son[1] = son;update ( x );//儿子变了 要及时上传修改信息 }
}

makeroot

换根,亦或者正大光明地发动政变,开始篡位,成为新的皇帝,这个时候管他三七二十一自己的手下势力已经足够强大,叫什么来着...√富可敌国,不服给我憋着,老子就是能当皇帝,而且这个国家都被颠倒了,老皇帝成了最卑微的娃
在这里插入图片描述

void reverse ( int x ) {swap ( tree[x].son[0], tree[x].son[1] );//翻转一下使得所有点的深度都倒过来了 tree[x].flag ^= 1;//flag为翻转标记 
}
void MakeRoot ( int x ) {//将x换成原树的根 access ( x );//x成为整个splay里面深度最深的点 splay ( x );//此splay里面的所有点都在x左边reverse ( x );
}

split

求两点之间的路径,别称太子与其它王朝的皇位继承人甚至是皇帝偷偷摸摸小花园
为什么是太子呢?看我们的模板就是太子为了不被判通敌叛国乱搞罪,决心发动政变,当了皇上后就理所应当的两国联姻,喜结连理,然后就可以通过小花园路上所有人走向他啦赶脚像是偶像剧里面的光芒万丈时刻,男主等着男主踏着日光带着旁人的艳羡,给他一切

void split ( int x, int y ) {//拉出x-y的路径成为一个splay 此处写法把y变成splay的根 MakeRoot ( x );access ( y );//打通x-y 两个就在一个splay里面了 y是深度最深的 splay ( y );//此时y的左子树就是x-y路径了且y没有右子树 
}

findroot

找根,绰号皇室继承人寻找自己现在所在王朝到底是哪个在做皇帝,方便以后篡位
这个寻找方式也是没谁了!先把自己跟该王朝的皇帝打通,然后自己篡位当皇帝,最后在一直往下面走去找变成卑微小生的老皇帝,说我知道你是皇帝了,你回来吧,我以后再篡位,够可以,够不要脸!
在这里插入图片描述

int FindRoot ( int x ) {//找到x所在原树的树根 access ( x );splay ( x );while ( tree[x].son[0] ) {pushdown ( x );x = tree[x].son[0];}splay ( x );return x;
}

link

连边,理解为:皇室继承人与自己的心上人确定关系之际
但是再怎么也不能乱伦,所以必须先判断一下相爱的两人是否在同一个王朝里面有祖孙关系,发现相爱后一个人成了自己的爸爸我把你当挚爱,你竟然想当我爸爸
在这里插入图片描述

void link ( int x, int y ) {//连一条x-y的边 此处写法x的父亲指向y MakeRoot ( x );if ( FindRoot ( y ) == x )//两点已经在同一子树中 不能再连边 return;tree[x].f = y;/*如果题目保证连边合法 代码可简化为: MakeRoot ( x );tree[x].fa = y;*/
}

cut

断边,含义皇室继承人刚刚确定关系就狠心抛弃以往的宠妃(爸爸),期待着下一个新欢(爸爸),但是这不能皇室继承人自己yy必须两人是彼此确认直系关系了的
在这里插入图片描述

void cut ( int x, int y ) {//将x-y的边断开 MakeRoot ( x );if ( FindRoot ( y ) != x || tree[y].f != x || tree[y].son[0] )return;//x在findroot(y)后重新转到了根tree[y].f = tree[x].son[1] = 0;update ( x );//少了个儿子 要及时更新 /*x-y之间有边要满足连通性(在同一个splay) 存在父子关系 y没有左儿子因为access(y)后 假如x-y在同一splay中而没有直接连边 那么这条路径上就一定有其他的点在中序遍历时会位于x-y之间那么可能y的父亲不是x 或者 y的父亲是x 其它的点就在y左子树里 *//*如果维护了size还可以换法判断 因为access后按道理应该只有x-y两个点if( FindRoot ( y ) != x || tree[x].siz > 2 )return;*//*如果题目保证断边合法 可以简化为:split ( x, y );tree[x].fa = tree[y].son[0] = 0;update ( y );*/
}

封装版

namespace LCT {struct node { int son[2], fa, tag; }t[maxn];bool root( int x ) { return t[t[x].fa].son[0] ^ x and t[t[x].fa].son[1] ^ x; }void reverse( int x ) { swap( t[x].son[0], t[x].son[1] ); t[x].tag ^= 1; }void pushdown( int x ) {if( ! t[x].tag ) return;if( t[x].son[0] ) reverse( t[x].son[0] );if( t[x].son[1] ) reverse( t[x].son[1] );t[x].tag ^= 1;}void rotate( int x ) {int fa = t[x].fa;int Gfa = t[fa].fa;int d = t[fa].son[1] == x;if( ! root( fa ) ) t[Gfa].son[t[Gfa].son[1] == fa] = x;t[x].fa = Gfa;if( t[x].son[d ^ 1] ) t[t[x].son[d ^ 1]].fa = fa;t[fa].son[d] = t[x].son[d ^ 1];t[x].son[d ^ 1] = fa;t[fa].fa = x;}void splay( int x ) {sta[++ top] = x; int y = x;while( ! root( y ) ) sta[++ top] = y = t[y].fa;while( top ) pushdown( sta[top --] );while( ! root( x ) ) {int fa = t[x].fa, Gfa = t[fa].fa;if( ! root( fa ) ) (t[Gfa].son[0] == fa) ^ (t[fa].son[0] == x) ? rotate( x ) : rotate( fa );rotate( x ); }}void access( int x ) { for( int son = 0;x;son = x, x = t[x].fa ) splay( x ), t[x].son[1] = son; }void makeroot( int x ) { access( x ); splay( x ); reverse( x ); }void split( int x, int y ) { makeroot( x ); access( y ); splay( y ); }void link( int x, int y ) { makeroot( x ); t[x].fa = y; }void cut( int x, int y ) { split( x, y ); t[x].fa = t[y].son[0] = 0; }int findroot( int x ) { access( x ); splay( x ); while( t[x].son[0] ) pushdown( x ), x = t[x].son[0]; splay( x ); return x; }bool check( int x, int y ) { makeroot( x ); return findroot( y ) == x; }
}

例题

题目

爪⑧,dbq我爪巴
在这里插入图片描述

code普通版

#include <cstdio>
#include <iostream>
using namespace std;
#define maxn 300005
struct node {int f, val, sum, flag, son[2];
}tree[maxn];
int n, m;
int st[maxn];void reverse ( int x ) {swap ( tree[x].son[0], tree[x].son[1] );tree[x].flag ^= 1;
}void update ( int x ) {tree[x].sum = tree[tree[x].son[0]].sum ^ tree[tree[x].son[1]].sum ^ tree[x].val;
}void pushdown ( int x ) {if ( tree[x].flag ) {if ( tree[x].son[0] )reverse ( tree[x].son[0] );if ( tree[x].son[1] )reverse ( tree[x].son[1] );tree[x].flag = 0;}
}bool isroot ( int x ) {return tree[tree[x].f].son[0] == x || tree[tree[x].f].son[1] == x;
}void rotate ( int x ) { int fa = tree[x].f; int Gfa = tree[fa].f;int k = ( tree[fa].son[1] == x );if ( isroot ( fa ) )tree[Gfa].son[tree[Gfa].son[1] == fa] = x;tree[x].f = Gfa; tree[fa].son[k] = tree[x].son[k ^ 1];if ( tree[x].son[k ^ 1] )tree[tree[x].son[k ^ 1]].f = fa;tree[x].son[k ^ 1] = fa;tree[fa].f = x;update ( fa );update ( x );
}void splay ( int x ) {int Top = 0, y = x;st[++ Top] = y;while ( isroot ( y ) )st[++ Top] = y = tree[y].f;while ( Top )pushdown ( st[Top -- ] );while ( isroot ( x ) ) {int fa = tree[x].f, Gfa = tree[fa].f;if ( isroot ( fa ) )( ( tree[Gfa].son[0] == fa ) ^ ( tree[fa].son[0] == x ) ) ? rotate ( x ) : rotate ( fa );rotate ( x );}
}void access ( int x ) {for ( int son = 0;x;son = x, x = tree[x].f ) {splay ( x );tree[x].son[1] = son;update ( x );}
}void MakeRoot ( int x ) {access ( x );splay ( x );reverse ( x );
}int FindRoot ( int x ) {access ( x );splay ( x );while ( tree[x].son[0] ) {pushdown ( x );x = tree[x].son[0];}splay ( x );return x;
}void split ( int x, int y ) {MakeRoot ( x );access ( y );splay ( y );
}void link ( int x, int y ) {MakeRoot ( x );if ( FindRoot ( y ) == x ) return;tree[x].f = y;
}void cut ( int x, int y ) {MakeRoot ( x );if ( FindRoot ( y ) != x || tree[y].f != x || tree[y].son[0] )return;tree[y].f = tree[x].son[1] = 0;update ( x );
}int main() {scanf ( "%d %d", &n, &m );for ( int i = 1;i <= n;i ++ )scanf ( "%d", &tree[i].val );int opt, x, y;for ( int i = 1;i <= m;i ++ ) {scanf ( "%d %d %d", &opt, &x, &y );switch ( opt ) {case 0 : {split ( x, y );printf ( "%d\n", tree[y].sum );break;}case 1 : link ( x, y ); break;case 2 : cut ( x, y ); break;case 3 : {splay ( x );tree[x].val = y;break;}}}return 0;
}

code封装版

#include <cstdio>
#include <iostream>
using namespace std;
#define maxn 300005
struct Link_Cut_Tree {struct node {int f, val, sum, flag, son[2];}tree[maxn];int st[maxn];void reverse ( int x ) {swap ( tree[x].son[0], tree[x].son[1] );tree[x].flag ^= 1; }void update ( int x ) {tree[x].sum = tree[tree[x].son[0]].sum ^ tree[tree[x].son[1]].sum ^ tree[x].val;}void pushdown ( int x ) {if ( tree[x].flag ) {if ( tree[x].son[0] )reverse ( tree[x].son[0] );if ( tree[x].son[1] )reverse ( tree[x].son[1] );tree[x].flag = 0;}}bool isroot ( int x ) {return tree[tree[x].f].son[0] == x || tree[tree[x].f].son[1] == x;}void rotate ( int x ) { int fa = tree[x].f; int Gfa = tree[fa].f;int k = ( tree[fa].son[1] == x );if ( isroot ( fa ) )tree[Gfa].son[tree[Gfa].son[1] == fa] = x;tree[x].f = Gfa; tree[fa].son[k] = tree[x].son[k ^ 1];if ( tree[x].son[k ^ 1] )tree[tree[x].son[k ^ 1]].f = fa;tree[x].son[k ^ 1] = fa;tree[fa].f = x;update ( fa );update ( x );}void splay ( int x ) {int Top = 0, y = x;st[++ Top] = y;while ( isroot ( y ) )st[++ Top] = y = tree[y].f;while ( Top )pushdown ( st[Top -- ] );while ( isroot ( x ) ) {int fa = tree[x].f, Gfa = tree[fa].f;if ( isroot ( fa ) )( ( tree[Gfa].son[0] == fa ) ^ ( tree[fa].son[0] == x ) ) ? rotate ( x ) : rotate ( fa );rotate ( x );}}void access ( int x ) {for ( int son = 0;x;son = x, x = tree[x].f ) {splay ( x );tree[x].son[1] = son;update ( x ); }}void MakeRoot ( int x ) {access ( x ); splay ( x );reverse ( x );}int FindRoot ( int x ) { access ( x );splay ( x );while ( tree[x].son[0] ) {pushdown ( x );x = tree[x].son[0];}splay ( x );return x;}void split ( int x, int y ) {MakeRoot ( x );access ( y ); splay ( y );}void link ( int x, int y ) { MakeRoot ( x );if ( FindRoot ( y ) == x ) return;tree[x].f = y;}void cut ( int x, int y ) { MakeRoot ( x );if ( FindRoot ( y ) != x || tree[y].f != x || tree[y].son[0] )return;tree[y].f = tree[x].son[1] = 0;update ( x );}}LCT;
int n, m;int main() {scanf ( "%d %d", &n, &m );for ( int i = 1;i <= n;i ++ )scanf ( "%d", &LCT.tree[i].val );int opt, x, y;for ( int i = 1;i <= m;i ++ ) {scanf ( "%d %d %d", &opt, &x, &y );switch ( opt ) {case 0 : {LCT.split ( x, y );printf ( "%d\n", LCT.tree[y].sum );break;}case 1 : LCT.link ( x, y ); break;case 2 : LCT.cut ( x, y ); break;case 3 : {LCT.splay ( x );LCT.tree[x].val = y;break;}}}return 0;
}

如果本蒟蒻乱写的对您有帮助,点个赞呗(づ ̄3 ̄)づ╭❤~
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317986.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

迈向现代化的 .Net 配置指北

1. 欢呼 .NET Standard 时代我现在已不大提 .Net Core&#xff0c;对于我来说&#xff0c;未来的开发将是基于 .NET Standard&#xff0c;不仅仅是 面向未来 &#xff0c;也是 面向过去&#xff1b;不只是 .Net Core 可以享受便利&#xff0c; .NET Framework 不升级一样能享受…

YBTOJ洛谷P2042:维护数列(平衡树)

文章目录题目描述解析删除区间插入数列修改&翻转区间和&最大子段和代码传送门题目描述 解析 阴间题… 这不是裸的板子吗&#xff1f; 国赛真的有人能把这题写出来吗… 应该算一道练习作用很强的题了 写完这题&#xff0c;各种平衡树维护区间操作的方法可以说是毕业了吧…

CAP 2.4版本发布,支持版本隔离特性

前言自从上次 CAP 2.3 版本发布 以来&#xff0c;已经过去了几个月的时间&#xff0c;这几个月比较忙&#xff0c;所以也没有怎么写博客&#xff0c;趁着2019年到来之际&#xff08;现在应该是2019年开始的时候&#xff09;&#xff0c;CAP也发布了2018年的最后一个大版本 2.4&…

【周末狂欢赛7】【NOIP模拟赛】七夕祭,齿轮(dfs),天才黑客

文章目录T1题目题解codeT2题目题解codeT3题目题解codeT1 题目 七夕节因牛郎织女的传说而被扣上了「情人节」的帽子。于是TYVJ今年举办了一次线下七夕祭。Vani同学今年成功邀请到了cl同学陪他来共度七夕&#xff0c;于是他们决定去TYVJ七夕祭游玩。 TYVJ七夕祭和11区的夏祭的…

.NET Core 如何为项目提供高性能解决方案?

本系列&#xff0c;我们将探讨.NET Core 的一些好处&#xff0c;以及它如何为市场提供高性能解决方案&#xff0c;为传统.NET 开发人员和技术人员提供帮助。正文前言随着.NET Core 2.0 在 2016 年首次发布&#xff0c;微软拥有了这个通用、模块化、跨平台开源项目的下一个主要版…

[2.9训练]【CF909C】Python Indentation,【CF909D】Colorful Points,【CF909E】Coprocessor

文章目录T1&#xff1a;Python Indentation题目题解codeT2&#xff1a;Colorful Points题目题解codeT3&#xff1a;Coprocessor题目题解codeT1&#xff1a;Python Indentation 题目 题目描述 In Python, code blocks don’t have explicit begin/end or curly braces to mark…

Docker最全教程之使用Tencent Hub来完成CI(十)

本周更新两篇&#xff0c;保证不太监&#xff01;在本系列教程中&#xff0c;笔者希望将必要的知识点围绕理论、流程&#xff08;工作流程&#xff09;、方法、实践来进行讲解&#xff0c;而不是单纯的为讲解知识点而进行讲解。也就是说&#xff0c;笔者希望能够让大家将理论、…

[2.7]【CF933A】A Twisty Movement【CF926B】Add Points【CF917A】The Monster【CF919E】Congruence Equation

文章目录T1&#xff1a;A Twisty Movement题目题解codeT2&#xff1a;Add Points题目题解codeT3&#xff1a;The Monster题目题解codeT4&#xff1a;Congruence Equation题目题解codeT1&#xff1a;A Twisty Movement 题目 题目 题解 因为aia_iai​1/21/21/2&#xff0c;于…

LIS最长上升子序列

LIS算是比较经典的问题&#xff0c;常用的是O(n^2)的方法 for(int i1;i<n;i){dp[i]1;for(int j1;j<i;j){if(a[j]<a[i])dp[i]max(dp[i],dp[j]1);}mxmax(mx,dp[i]);}我们这里优化成O(nlogn) 我们模拟一个栈stack&#xff0c;每读入一个数&#xff0c;如果这个数大于栈顶…

EF Core 数据库 Provider 一览

当 EF Core 1.x 系列和 2.0 版本之间经过重大的重写时&#xff0c;所有 EF Core 数据库 Provider 都受到重创。从那时起&#xff0c;各种私人和商业开发团队一直在努力填补这个空白。正文当 EF Core 1.x 系列和 2.0 版本之间经过重大的重写时&#xff0c;所有 EF Core 数据库 P…

[3.3训练赛]One-Dimensional(矩阵快速幂),Freda的迷宫(无向图强连通分量+并查集),一道防AK好题

文章目录T1:One-DimensionaltitlesolutioncodeT2:【NOIP模拟赛】Freda的迷宫titlesolutioncodeT3:【NOIP模拟赛】一道防AK好题titlesolutioncode确实没想到自己写文章能隔这么久&#xff0c;鸽王预警 T1:One-Dimensional title 考虑一个含有 N 个细胞的一维细胞自动机。细胞…

牛客网专题 概率dp

文章目录概念&#xff1a;例题引入&#xff1a;解答&#xff1a;Happy Running NC15532题意&#xff1a;题解&#xff1a;代码&#xff1a;poj2096 NC106693 Collecting Bugs题意&#xff1a;题解&#xff1a;代码&#xff1a;NC210477 带富翁题意&#xff1a;题解&#xff1a;…

.NET Core 3.0 特性初探:C# 8、WPF、Windows Forms、EF Core

.NET Core 的下一个主要版本最近进入了预览阶段&#xff0c;.NET Core 3.0 将支持使用 Windows Presentation Foundation &#xff08;WPF&#xff09;、Windows Forms&#xff08;WinForms&#xff09;、Entity Framework &#xff08;EF&#xff09;、Blazor、 C# 8 和.NET S…

YBTOJ洛谷P4074:糖果公园(树上莫队)

文章目录解析update:代码所谓树上莫队&#xff0c;就是在树上的莫队 &#xff08;逃&#xff09; 传送门 解析 似乎就是树上的这道题 考虑如何转化为序列问题呢? 考虑dfs序 但是又一个问题。。。 似乎这条链的dfs序不连续啊 树剖一下就好啦 考虑更阳间的方法 求出这棵树的欧…

【用梨泰院class中的财阀世家带你洞悉替罪羊树】Scapegoat Tree原理,模板,例题

我想写在前面&#xff0c;本文财阀世家全是虚构&#xff0c;没有诋毁之意&#xff0c;如有雷同&#xff0c;纯属巧合 红色预警&#xff01;&#xff01;&#xff01;红色预警 文章目录Scapegoat Tree概念模板变量声明Bad函数判断是否需要重构理解模板rebuild重构理解模板inser…

领域驱动设计,让程序员心中有码(五)

1 从搬砖谈领域对象有一个古老的故事&#xff0c;大概是这样的。作者问三个建筑工地上的工人他们在干什么&#xff1f;有一个没精打采的说&#xff0c;我在挖洞&#xff01;而另一一个人却说&#xff0c;我在盖一座房子。还有一个人说&#xff0c;我在建立一座巨大的城市。…

.NET Core实战项目之CMS 第十四章 开发篇-防止跨站请求伪造(XSRF/CSRF)攻击处理...

通过 ASP.NET Core&#xff0c;开发者可轻松配置和管理其应用的安全性。 ASP.NET Core 中包含管理身份验证、授权、数据保护、SSL 强制、应用机密、请求防伪保护及 CORS 管理等等安全方面的处理。 通过这些安全功能&#xff0c;可以生成安全可靠的 ASP.NET Core 应用。而我们这…

模板:左偏树

文章目录解析可以解决的问题定义&#xff1a;左偏树的基本性质基本结论操作合并访问与删除堆顶元素插入元素批量插入删除已知元素所谓左偏树&#xff0c;就是往左偏的树 下面介绍一下它的一个兄弟&#xff1a; 《右偏树》 &#xff08;逃&#xff09; 解析 所谓左偏树&#…

迎开学水题狂欢赛(舞踏会[dp+三叉树],HH去散步[矩阵快速幂],排序[模拟],铁路旅行[线段树])

快速简单记录老师口胡&#xff08;可能就我自己看得懂了吧…&#xff09; 文章目录T1&#xff1a;舞踏会titlesolutioncodeT2&#xff1a;HH去散步titlesolutioncodeT3&#xff1a;排序titlesolutioncodeT4&#xff1a;铁路旅行titlesolutioncodeT1&#xff1a;舞踏会 title …

CSP2021提高组复赛解析

前言 终于出成绩了我可以写博客辣&#xff0c;官方数据还没出就先放洛谷的题目链接了。 正题 T1-廊桥分配 https://www.luogu.com.cn/problem/P7913 题目大意 有m1m_1m1​种一类飞机&#xff0c;m2m_2m2​种二类飞机&#xff0c;每个飞机有一个占用时间的区间。要给两类飞机…