【模板】多标记 LCT
代码如下
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 51061;
struct node {
node *l, *r, *p;
int rev, val;
LL sum, add, mul, sz;
node() {
l = r = p = NULL;
sum = add = rev = 0;
mul = val = sz = 1;
}
void unsafe_reverse() {
swap(l, r);
rev ^= 1;
}
void unsafe_add(LL x) {
sum = (sum + x * sz) % mod;
add = (add + x) % mod;
val = (val + x) % mod;
}
void unsafe_mul(LL x) {
sum = sum * x % mod;
add = add * x % mod;
val = val * x % mod;
mul = mul * x % mod;
}
void pull() {
sum = val;
sz = 1;
if (l != NULL) {
l->p = this;
sum = (sum + l->sum) % mod;
sz += l->sz;
}
if (r != NULL) {
r->p = this;
sum = (sum + r->sum) % mod;
sz += r->sz;
}
}
void push() {
if (rev) {
if (l != NULL) {
l->unsafe_reverse();
}
if (r != NULL) {
r->unsafe_reverse();
}
rev = 0;
}
if (mul != 1) {
if (l != NULL) {
l->unsafe_mul(mul);
}
if (r != NULL) {
r->unsafe_mul(mul);
}
mul = 1;
}
if (add != 0) {
if (l != NULL) {
l->unsafe_add(add);
}
if (r != NULL) {
r->unsafe_add(add);
}
add = 0;
}
}
};
bool is_root(node *v) {
if (v == NULL) {
return false;
}
return (v->p == NULL) || (v->p->l != v && v->p->r != v);
}
void rotate(node *v) {
node *u = v->p;
assert(u != NULL);
v->p = u->p;
if (v->p != NULL) {
if (v->p->l == u) {
v->p->l = v;
}
if (v->p->r == u) {
v->p->r = v;
}
}
if (v == u->l) {
u->l = v->r;
v->r = u;
}
if (v == u->r) {
u->r = v->l;
v->l = u;
}
u->pull();
v->pull();
}
void deal_with_push(node *v) {
static stack<node*> s;
while (1) {
s.push(v);
if (is_root(v)) {
break;
}
v = v->p;
}
while (!s.empty()) {
s.top()->push();
s.pop();
}
}
void splay(node *v) {
deal_with_push(v);
while (!is_root(v)) {
node *u = v->p;
if (!is_root(u)) {
if ((v == u->l) ^ (u == u->p->l)) {
rotate(v);
} else {
rotate(u);
}
}
rotate(v);
}
}
void access(node *v) {
node *u = NULL;
while (v != NULL) {
splay(v);
v->r = u;
v->pull();
u = v;
v = v->p;
}
}
void make_root(node *v) {
access(v);
splay(v);
v->unsafe_reverse();
}
node* find_root(node *v) {
access(v);
splay(v);
while (v->l != NULL) {
v->push();
v = v->l;
}
splay(v);
return v;
}
void link(node *v, node *u) {
if (find_root(v) != find_root(u)) {
make_root(v);
v->p = u;
}
}
void cut(node *v, node *u) {
make_root(v);
if (find_root(u) == v && u->p == v && u->l == NULL) {
u->p = v->r = NULL;
v->pull();
}
}
void split(node *v, node *u) {
make_root(v);
access(u);
splay(u);
}
int main() {
//freopen("data.in", "r", stdin);
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int n, m;
cin >> n >> m;
vector<node*> t(n + 1);
for (int i = 1; i <= n; i++) {
t[i] = new node();
}
for (int i = 1; i < n; i++) {
int x, y;
cin >> x >> y;
link(t[x], t[y]);
}
while (m--) {
string opt;
int x, y;
cin >> opt >> x >> y;
if (opt[0] == '+') {
int c;
cin >> c;
split(t[x], t[y]);
t[y]->unsafe_add(c);
}
if (opt[0] == '-') {
int u, v;
cin >> u >> v;
cut(t[x], t[y]);
link(t[u], t[v]);
}
if (opt[0] == '/') {
split(t[x], t[y]);
cout << t[y]->sum % mod << endl;
}
if (opt[0] == '*') {
int c;
cin >> c;
split(t[x], t[y]);
t[y]->unsafe_mul(c);
}
}
for (int i = 1; i <= n; i++) {
delete t[i];
}
return 0;
}
【模板】多标记 LCT的更多相关文章
- 洛谷P1501 [国家集训队]Tree II(打标记lct)
题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...
- 洛谷P3366 【模板】最小生成树(LCT)
[模板]最小生成树 题目传送门 解题思路 用LCT来维护最小生成树. 除了把各顶点作为节点外,每条边也都视为一个节点.对于要加入的边\(e\),检查其两顶点\(x\)和\(y\)是否在同一棵树中,如果 ...
- [模板] 动态树/LCT
简介 LCT是一种数据结构, 可以维护树的动态加边, 删边, 维护链上信息(满足结合律), 单次操作时间复杂度 \(O(\log n)\).(不会证) 思想类似树链剖分, 因为splay可以换根, 用 ...
- bzoj2049-洞穴勘测(动态树lct模板题)
Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好 ...
- 树上数据结构——LCT
目录 树上数据结构--LCT 概述 基本概念 核心操作 其他操作 完整模板 树上数据结构--LCT 概述 LCT是一种强力的树上数据结构,支持以下操作: 链上求和 链上求最值 链上修改 子树修改 子树 ...
- 12月15日smarty模板基本语法
smarty基本语法: 1.注释:<{* this is a comment *}>,注意左右分隔符的写法,要和自己定义的一致. <{* I am a Smarty comment, ...
- Mustache.js前端模板引擎源码解读
mustache是一个很轻的前端模板引擎,因为之前接手的项目用了这个模板引擎,自己就也继续用了一会觉得还不错,最近项目相对没那么忙,于是就抽了点时间看了一下这个的源码.源码很少,也就只有六百多行,所以 ...
- 利用html模板生成Word文件(服务器端不需要安装Word)
利用html模板生成Word文件(服务器端不需要安装Word) 由于管理的原因,不能在服务器上安装Office相关组件,所以只能采用客户端读取Html模板,后台对模板中标记的字段数据替换并返回给客户端 ...
- bzoj2243-染色(动态树lct)
解析:增加三个变量lc(最左边的颜色),rc(最右边的颜色),sum(连续相同颜色区间段数).然后就是区间合并的搞法.我就不详细解释了,估计你已经想到 如何做了. 代码 #include<cst ...
随机推荐
- 【LOJ】#3120. 「CTS2019 | CTSC2019」珍珠
LOJ3120 52pts \(N - D >= 2M\)或者\(M = 0\)那么就是\(D^{N}\) 只和数字的奇偶性有关,如果有k个奇数,那么必须满足\(N - k >= 2M\) ...
- BEGIN_MESSAGE_MAP和END_MESSAGE_MAP()
这两个宏表示这个类的消息映射开始和结束,中间的宏定义定义了此类的所有的消息映射.前面的afx_msg void OnPaint():只是声明OnPaint()函数的一个消息处理函数,然后是OnPain ...
- 从入门到自闭之Python--Django Rest_Framework
核心思想: 缩减编写api接口的代码 Django REST framework是一个建立在Django基础之上的Web 应用开发框架,可以快速的开发REST API接口应用.在REST framew ...
- mac手册汉化 2019
1.安装依赖 brew install automake brew install opencc 2.编译 wget https://github.com/man-pages-zh/manpages- ...
- 1-Perl 简介
Perl 是 Practical Extraction and Report Language 的缩写,可翻译为 "实用报表提取语言".Perl 是高级.通用.直译式.动态的程序语 ...
- 《深入实践C++模板编程》之四——特例
1. 所谓模板特例,是针对符合某种条件的模板参数值集合另外声明的模板实现变体. template<typename T> class my_vector; template<> ...
- 利用Cmake 将最新版本OBS编译成windows版本。
准备工作: 1. VS2013 的最新更新版或者VS2015 2. QT Creater 5.7 https://www.qt.io/ 3. CMake (cmake-gui) 4. obs 依 ...
- 配置lombok到eclipse上去
使用maven导入lombok.jar包,可以帮助我们省略掉getter/setting方法. 1.pom.xml 添加依赖: <dependency> <groupId>or ...
- 【Javascript】 js的构造函数与原形对象的关系
构造函数只是提供了一个创建对象的模板,它并不是对象的原形. 对象的原形是构造函数的原形,即object. ----------------------------------------------- ...
- 使用webpack + momentjs时, 需要注意的问题
注意开发HTML页面charset, 如是不是utf-8, 比如是shift_jis, 一般会在webpack里用插件EncodingPlugin把开发的utf-8格式转码成shift_jis格式 ...