代码如下

#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的更多相关文章

  1. 洛谷P1501 [国家集训队]Tree II(打标记lct)

    题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...

  2. 洛谷P3366 【模板】最小生成树(LCT)

    [模板]最小生成树 题目传送门 解题思路 用LCT来维护最小生成树. 除了把各顶点作为节点外,每条边也都视为一个节点.对于要加入的边\(e\),检查其两顶点\(x\)和\(y\)是否在同一棵树中,如果 ...

  3. [模板] 动态树/LCT

    简介 LCT是一种数据结构, 可以维护树的动态加边, 删边, 维护链上信息(满足结合律), 单次操作时间复杂度 \(O(\log n)\).(不会证) 思想类似树链剖分, 因为splay可以换根, 用 ...

  4. bzoj2049-洞穴勘测(动态树lct模板题)

    Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好 ...

  5. 树上数据结构——LCT

    目录 树上数据结构--LCT 概述 基本概念 核心操作 其他操作 完整模板 树上数据结构--LCT 概述 LCT是一种强力的树上数据结构,支持以下操作: 链上求和 链上求最值 链上修改 子树修改 子树 ...

  6. 12月15日smarty模板基本语法

    smarty基本语法: 1.注释:<{* this is a comment *}>,注意左右分隔符的写法,要和自己定义的一致. <{* I am a Smarty comment, ...

  7. Mustache.js前端模板引擎源码解读

    mustache是一个很轻的前端模板引擎,因为之前接手的项目用了这个模板引擎,自己就也继续用了一会觉得还不错,最近项目相对没那么忙,于是就抽了点时间看了一下这个的源码.源码很少,也就只有六百多行,所以 ...

  8. 利用html模板生成Word文件(服务器端不需要安装Word)

    利用html模板生成Word文件(服务器端不需要安装Word) 由于管理的原因,不能在服务器上安装Office相关组件,所以只能采用客户端读取Html模板,后台对模板中标记的字段数据替换并返回给客户端 ...

  9. bzoj2243-染色(动态树lct)

    解析:增加三个变量lc(最左边的颜色),rc(最右边的颜色),sum(连续相同颜色区间段数).然后就是区间合并的搞法.我就不详细解释了,估计你已经想到 如何做了. 代码 #include<cst ...

随机推荐

  1. pramfs理论

    一.文件系统 1.百度百科: http://baike.baidu.com/link?url=WE3aLsszfbZZIPK-Vz8yPd799_RMqyfQZ4D-ETS5yd1nI8XzPK660 ...

  2. Sliding Puzzle

    On a 2x3 board, there are 5 tiles represented by the integers 1 through 5, and an empty square repre ...

  3. [转帖]calico网络原理及与flannel对比

    calico网络原理及与flannel对比 https://blog.csdn.net/ganpuzhong42/article/details/77853131 2017年09月05日 16:34: ...

  4. 2019-07-31 C#基础知识学习

    什么是进程:进程是系统中正在运行的一个程序,程序一旦运行就是进程. 什么是线程:线程是进程的一个实体,是进程的一条执行路径. 进程和线程的区别体现在以下几个方面: 1.地址空间和其他资源(如打开文件) ...

  5. git安装配置相关

    Git是一个分布式的版本控制系统,最初由Linus Torvalds编写,用作Linux内核代码的管理.在推出后,Git在其它项目中也取得了很大成功,尤其是在Ruby社区中.目前,包括Rubinius ...

  6. sysbench测试

    什么是基准测试 数据库的基准测试是对数据库的性能指标进行定量的.可复现的.可对比的测试. 基准测试与压力测试 基准测试可以理解为针对系统的一种压力测试.但基准测试不关心业务逻辑,更加简单.直接.易于测 ...

  7. Wannafly挑战赛24

    A. 石子游戏 Alice和Bob在玩游戏,他们面前有n堆石子,对于这些石子他们可以轮流进行一些操作,不能进行下去的人则输掉这局游戏.可以进行两种操作:1. 把石子数为奇数的一堆石子分为两堆正整数个石 ...

  8. Python 风格指南

    https://zh-google-styleguide.readthedocs.io/en/latest/google-python-styleguide/contents/ 目前个人遵循的基本规范 ...

  9. unity ugui image更换图片

    1:利用资源加载方式 using UnityEngine; using System.Collections; using UnityEngine.UI; public class ChangeIma ...

  10. pymssql文档(转)

    pymssql methods set_max_connections(number) -- Sets maximum number of simultaneous database connecti ...