LCT模板
之前一直用的LCT模板,因为其实个人对LCT和Splay不是很熟,所以用起来总觉得略略的坑爹,过了一段时间就忘了,但事实上很多裸的LCT要改的东西是不多的,所以今天写了些注释,以后可能套起模板来会得心应手一点吧- -0
#pragma warning(disable:4996)
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <map>
using namespace std; #define ll long long
#define maxn 200000
#define INF 0x3f3f3f3f
#define INP INF+1
#define MP make_pair void merge(int mxx[2], int nxx[2], int pval, int pnum)
{
if (pval>mxx[0]){
mxx[1] = mxx[0]; nxx[1] = nxx[0];
mxx[0] = pval; nxx[0] = pnum;
}
else if (pval == mxx[0]){
nxx[0] += pnum;
}
else if (pval>mxx[1]){
mxx[1] = pval; nxx[1] = pnum;
}
else if(pval==mxx[1]){
nxx[1] += pnum;
}
} struct Node
{
/* Splay items(need not to be modified)*/
Node *p, *ch[2];
/* end */ /* LCT items(need not to be modified)*/
bool isRoot;
Node *fa;
/* end */ /* tags to add(rev should always exist)*/
bool rev;
int add, cov;
/* end */ /* data need to be maintained*/
int val, size;
int mx[2], num[2];
/* end */ /* default value for the sentinel null(all the TAG and DATA should be set correcly)*/
Node(){
/* DATA */
val = 0; size=0;
mx[0] = mx[1] = -INF;
num[0] = num[1] = 0;
/* TAG */
rev = 0;add = 0; cov = INP;
}
/* end */ /* Splay function(need not to be modified)*/
void setc(Node *c, int d){
ch[d] = c;
c->p = this;
}
bool d(){
return p->ch[1] == this;
}
/* end */ /* update function(maintain for ALL the DATA)*/
void upd(){
size = ch[0]->size + ch[1]->size + 1;
mx[0] = ch[0]->mx[0]; num[0] = ch[0]->num[0];
mx[1] = ch[0]->mx[1]; num[1] = ch[0]->num[1];
merge(mx, num, val, 1);
merge(mx, num, ch[1]->mx[0], ch[1]->num[0]);
merge(mx, num, ch[1]->mx[1], ch[1]->num[1]);
}
/* end */ /* tags function(for ALL the TAG,write a function)*/
void revIt(){
rev ^= 1;
swap(ch[0], ch[1]);
}
void addIt(int vx){
add += vx;
val += vx;
if (mx[0] != -INF) mx[0] += vx;
if (mx[1] != -INF) mx[1] += vx;
}
void setIt(int vx){
add = 0;
cov = vx;
val = vx;
mx[0] = vx; num[0] = size;
mx[1] = -INF; num[1] = 0;
}
/* end */ void relax();
void setRoot(Node *f);
}Tnull, *null = &Tnull; /* function setRoot(need not to be modified) */
void Node::setRoot(Node *f){
fa = f;
isRoot = true;
p = null;
} /* function relax(need to be rewrite for ALL the TAG) */
void Node::relax(){
if (cov != INP){
for (int i = 0; i<2; ++i){
if (ch[i] != null) ch[i]->setIt(cov);
}
cov = INP;
}
if (add != 0){
for (int i = 0; i < 2; i++){
if (ch[i] != null) ch[i]->addIt(add);
}
add = 0;
}
if (rev){
for (int i = 0; i < 2; i++){
if (ch[i] != null) ch[i]->revIt();
}
rev = 0;
}
} /* memory part(add C=mem for every iteration)*/
Node mem[maxn], *C = mem; /* function make(need to set the default value for ALL the TAG and DATA)*/
Node *make(int v){
/* DATA */
C->size=1;
C->val = v;
C->mx[0] = v; C->num[0] = 1;
C->mx[1] = -INF; C->num[1] = 0;
/* TAG */
C->rev = 0; C->add = 0;
C->cov = INP;
/* Pointer(need not to be modified) */
C->ch[0] = C->ch[1] = null; C->isRoot = true;
C->p = null;
C->fa = null;
return C++;
} /* function rot(need not to be modified) */
void rot(Node *t){
Node *p = t->p;
p->relax();
t->relax();
bool d = t->d();
p->p->setc(t, p->d());
p->setc(t->ch[!d], d);
t->setc(p, !d);
p->upd();
if (p->isRoot){
p->isRoot = false;
t->isRoot = true;
t->fa = p->fa;
}
} /* function pushTo(need not to be modified) */
void pushTo(Node*t) {
static Node*stk[maxn]; int top = 0;
while (t != null) {
stk[top++] = t;
t = t->p;
}
for (int i = top - 1; i >= 0; --i) stk[i]->relax();
} /* function splay(need not to be modified) */
void splay(Node*u, Node*f = null) {
pushTo(u);
while (u->p != f) {
if (u->p->p == f)
rot(u);
else
u->d() == u->p->d() ? (rot(u->p), rot(u)) : (rot(u), rot(u));
}
u->upd();
} /* Node pointer array*/
Node *v[maxn];
/* The graph stored in the E*/
vector<int> E[maxn];
int n, nQ; /* BFS items, using for construct the Tree */
int que[maxn], fa[maxn], qh = 0, qt = 0;
int wht[maxn]; /* function BFS(need not to be modified) */
void bfs()
{
qh = qt = 0;
que[qt++] = 1;
fa[1] = -1;
while (qh < qt){
int u = que[qh++];
for (int i = 0; i < E[u].size(); i++){
int e = E[u][i];
if (e != fa[u]){
fa[e] = u;
v[e]->fa = v[u];
que[qt++] = e;
}
}
}
} /* function expose(need not to be modified) */
Node *expose(Node *u)
{
Node *v;
for (v = null; u != null; v = u, u = u->fa){
splay(u);
u->ch[1]->setRoot(u);
u->setc(v, 1);
v->fa = u;
}
return v;
} /* function makeRoot(need not to be modified) */
void makeRoot(Node *u)
{
expose(u);
splay(u);
u->revIt();
} /* function addEdge(need not to be modified) */
void addEdge(Node *u, Node *v)
{
makeRoot(v);
v->fa = u;
} /* function delEdge(need not to be modified) */
void delEdge(Node *u, Node *v)
{
makeRoot(u);
expose(v); splay(u); u->setc(null, 1); u->upd();
v->setRoot(null);
} /* function find root(need not to be modified) */
Node *find_root(Node *u)
{
expose(u); splay(u);
while (u->ch[0] != null){
u = u->ch[0];
}
splay(u); return u;
} /* function used for query*/
/***************************
prototype:
void xPath(Node *u,Node *v,(int ax))
{
makeRoot(u);
expose(v);
splay(v);
v->xIt((ax))
}
***************************/
void addPath(Node *u, Node *v, int ax)
{
makeRoot(u);
expose(v);
splay(v);
v->addIt(ax);
} void setPath(Node *u, Node *v, int ax)
{
makeRoot(u);
expose(v);
splay(v);
v->setIt(ax);
} pair<int, int> queryPath(Node *u, Node *v){
makeRoot(u);
expose(v);
splay(v);
return MP(v->mx[1], v->num[1]);
} int main()
{
int T; cin >> T;int ca=0;
while (T--)
{
/* Things to do */
/*************************
C=mem;
initialize E;
read in the wht for nodes;
make for each node;
bfs();
solve for query();
**************************/
C = mem;
scanf("%d%d", &n, &nQ);
for (int i = 1; i <= n; i++){
scanf("%d", wht + i);
v[i] = make(wht[i]);
}
for (int i = 0; i <= n; i++) E[i].clear();
int ui, vi;
for (int i = 0; i < n - 1; i++){
scanf("%d%d", &ui, &vi);
E[ui].push_back(vi); E[vi].push_back(ui);
}
bfs();
int cmd, xi, yi, ai, bi;
Node *nx, *ny, *na, *nb;
printf("Case #%d:\n",++ca);
while (nQ--){
scanf("%d", &cmd);
if (cmd == 1) scanf("%d%d%d%d", &xi, &yi, &ai, &bi);
else if (cmd == 2 || cmd == 3) scanf("%d%d%d", &ai, &bi, &xi);
else scanf("%d%d", &ai, &bi); if (cmd == 1){
nx = v[xi]; ny = v[yi];
na = v[ai]; nb = v[bi];
delEdge(nx, ny);
addEdge(na, nb);
}
else if (cmd == 2){
nx = v[ai]; ny = v[bi];
setPath(nx, ny, xi);
}
else if (cmd == 3){
nx = v[ai]; ny = v[bi];
addPath(nx, ny, xi);
}
else{
nx = v[ai]; ny = v[bi];
pair<int, int> ans = queryPath(nx, ny);
if (ans.first <= -INF) printf("ALL SAME\n");
else printf("%d %d\n", ans.first, ans.second);
}
}
}
return 0;
}
LCT模板的更多相关文章
- LCT 模板及套路总结
这一个月貌似已经考了无数次\(LCT\)了..... 保险起见还是来一发总结吧..... A. LCT 模板 \(LCT\) 是由大名鼎鼎的 \(Tarjan\) 老爷发明的. 主要是用来维护树上路径 ...
- [洛谷P1501] [国家集训队]Tree II(LCT模板)
传送门 这是一道LCT的板子题,说白了就是在LCT上支持线段树2的操作. 所以我只是来存一个板子,并不会讲什么(再说我也不会,只能误人子弟2333). 不过代码里的注释可以参考一下. Code #in ...
- LuoguP3690 【模板】Link Cut Tree (动态树) LCT模板
P3690 [模板]Link Cut Tree (动态树) 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两 ...
- BZOJ2002 & LCT模板(分块不会搞)
题意: 看题. 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿 着一条直线摆上n个装置,每个装置设定初 ...
- bzoj2049-洞穴勘测(动态树lct模板题)
Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好 ...
- Luogu 3690 LCT - 模板
推荐几篇比较好的博客: FlashHu 的 讲解比较好 : 传送门 Candy 的 代码~ : 传送门 以及神犇Angel_Kitty的 学习笔记: 传送门 Code V 模板 #include< ...
- BZOJ 1180 / 2843 LCT模板题_双倍经验
一大早上到机房想先拍一下模板,热热身. 结果....对照着染色敲的 LCT 竟然死活也调不过去(你说我抄都能抄错) 干脆自己重新敲了一遍,10min就敲完了....... 还是要相信自己 Code: ...
- BZOJ3282: Tree (LCT模板)
Description 给定N个点以及每个点的权值,要你处理接下来的M个操作. 操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和 ...
- LCT模板(学习笔记)(洛谷3690)(加边,删边,修改点权)
最近学习了一波LCT qwq 强势安利Flashhu的博客!!!!! 真的特别详细(可惜我不会弄链接) 如果有想要学习\(LCT\)的同学,可以直接看他的博客 我这里就简单写一点自己的体会啊. \(L ...
随机推荐
- Unity Scripting Tutorials 要点记录
(搬运自我在SegmentFault的博客) 这几天通过Unity官网的Unity Scripting Tutorials的视频学习Unity脚本,观看的过程中做了记录.现在,整理了一下笔记,供自己以 ...
- LaTeX插入jpg图片: 使用graphicx
首先要包含宏包 \usepackage{graphicx} \begin{figure}[ht!] \centering \includegraphics[width=90mm]{fixed_dome ...
- R中统计量的中英文解释
Intercept————截距 formula————公式 Residual standard error残差标准差: 1.319 on 10 degrees of freedom 自由度为10 ...
- Douglas Crockford: entityify & deentityify
大神之字符与字符实体的相互转换方法 // & to & if (!String.prototype.entityify) { String.prototype.entityify = ...
- JVM规范小结
JVM规范组成: 1. 字节码(ByteCode): 以Class或Interface为基本单位, 具有固定结构. 2. 指令集(InstructionSet): 每个指令用一个字节表示, 最多256 ...
- java 切换
Android L之后推荐使用JDK7编译程序,这是自然发展规律,就像是4年前编译Android 1.6需要使用JDK5一样. 多版本JDK是可以共存的,只需要使用update-alternative ...
- iOS学习之Object-C语言属性和点语法
一.属性 1.属性的声明:在.h文件中使用@property声明属性. @property NSString *name; 2.属性的作用是生成setter以 ...
- 制作越狱版本的ipa文件
1.新建项目,证书选择开发者自己创建的证书 2.编译项目,在工程左侧树形菜单中,找到Product,找到编译后的项目,邮件,找到.app文件路径. 3.将这个app文件拖入到iTunes,邮件点击图标 ...
- linux下操作
一.没有正确安装GNOME电源管理器的默认配置 二.oracle启停 1. linux下启动oraclesu - oraclesqlplus /nologconn /as sysdbastartupe ...
- 3-附1 ->和*的区别
问题: c++ .和 ->有什么区别? 还有什么是继承什么是派生?-------------------------------------------------------------- 比 ...