【模板】多标记 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 ...
随机推荐
- Servlet 使Session设置失效
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletExcep ...
- firewall-cmd 的简单使用 进行端口转发的使用
今天本来想用 ssh 做端口转发 但是命令死活想不起来了.. 没办法改用firewall-cmd 来进行处理 方法: 1. 首先不能关防火墙 systemctl enable firewalld sy ...
- 谈谈Java中的集合list、set、map之间的区别
参考文献:https://www.cnblogs.com/IvesHe/p/6108933.html 我这里只总结其区别,具体的说明,请查看参考文献,讲的很详细. A.list接口,实现子类有:arr ...
- 基于Centos 搭建Jenkins环境
⒈简介 Jenkins 是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能. ⒉Java安装 首先我们需要准备 ...
- vue技术分享之你可能不知道的7个秘密
本文是vue源码贡献值Chris Fritz在公共场合的一场分享,觉得分享里面有不少东西值得借鉴,虽然有些内容我在工作中也是这么做的,还是把大神的ppt在这里翻译一下,希望给朋友带来一些帮助. 一.善 ...
- T100——动态更改Label的说明
例子: #設定科目名稱 IF g_prog = 'aapt300' THEN CALL cl_set_comp_att_text("lbl_apca036",cl ...
- windows 控制台默认为UTF-8显示的方法
这里需要先了解些内容: CHCP CHCP是MS DOS中的命令,用来显示或设置活动代码页编号的.用法是: CHCP [nnn] 其中nnn指定的是代码页的编号.这个参数是可选的,在命令行下如果不指定 ...
- Jmeter之Linux安装(Xshell),分布式运行Linux作为slave机
甲方爸爸要求,用Linux压测...... 所以在公司服务器Linux上搭建Jmeter 但实际一个Jmeter程序也有程序瓶颈~ 所以在Jmeter瓶颈下,搭建分布式压测系统.(也许可以尝试在一 ...
- jq之display:none与visible:hidden
http://www.cnblogs.com/linxiong945/p/4075146.html 今天学习到jquery的hide()部分时,突然有一个想法,jquery中的隐藏/显示部分的实现是给 ...
- ThreadLocal的原理与使用
前言 在java web项目中,经常会使用到单例对象,从服务器启动那一时刻就实例化全局对象.然后会对某些全局对象的属性进行修改之类的操作,但是我们知道项目一般都是部署到tomcat.Jboss之类的服 ...