lct 基础(' '   ) 就当个纪念吧(' '    )  毕竟写了4h, cut 部分一直naive 总是想找谁是儿子,然后最后发现直接提根就好了啊(' '   )

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; typedef long long ll;
const ll mod = 51061;
const ll maxn = 100010; ll pl(ll a, ll b) {
ll ret = a + b;
if(ret >= mod) ret %= mod;
return ret;
} ll mul(ll a, ll b) {
return a * b % mod;
} struct node {
ll ans, lm, lp, lr, size, data, p;
node *son[2], *fa;
}e[maxn]; ll ne = 0; void test(node* x) {
if(!x) return;
cout << x-> data <<" "<<x-> size <<" "<< x-> p << endl;
for(ll i = 0; i < 2; ++ i) test(x-> son[i]);
} void update(node* x) {
x-> ans = x-> data, x-> size = 1;
for(ll i = 0; i < 2; ++ i)
if(x-> son[i])
x-> ans = pl(x-> ans, x-> son[i]-> ans), x-> size = pl(x-> son[i]-> size, x-> size);
} void swap(node* &a, node* &b) {
node* mid = a; a = b, b = mid;
} void pushdown(node* x) {
if(!x || (!x-> lp && !x-> lr && x-> lm == 1)) return;
if(x-> lr) {
swap(x-> son[0], x-> son[1]);
for(ll i = 0; i < 2; ++ i) if(x-> son[i]) x-> son[i]-> lr ^= 1;
x-> lr = 0;
}
for(ll i = 0; i < 2; ++ i) {
if(x-> son[i]) {
x-> son[i]-> ans = pl(mul(x-> son[i]-> ans, x-> lm), mul(x-> son[i]-> size, x-> lp));
x-> son[i]-> data = pl(mul(x-> son[i]->data, x-> lm), x-> lp);
x-> son[i]-> lp = pl(mul(x-> son[i]-> lp, x-> lm), x-> lp);
x-> son[i]-> lm = mul(x-> son[i]-> lm, x-> lm);
}
}
x-> lm = 1, x-> lp = 0;
} void rotate(node* x, ll f) {
node* y = x-> fa;
if(y-> fa) {
if(y-> fa-> son[0] == y) y-> fa-> son[0] = x;
else y-> fa-> son[1] = x;
}
x-> fa = y-> fa; x-> size = y-> size; y-> fa = x; x-> p = y-> p;
x-> ans = y-> ans;
y-> son[f] = x-> son[!f];
if(x-> son[!f]) x-> son[!f]-> fa = y;
x-> son[!f] = y;
update(y);
} void splay(node* x, node* f) {
pushdown(x);
while(x-> fa != f) {
if(x-> fa-> fa == f) {
pushdown(x-> fa-> fa), pushdown(x-> fa), pushdown(x);
ll a = x-> fa-> son[0] == x ? 0 : 1;
rotate(x, a);
}
else {
node *y = x-> fa, *z = y-> fa;
pushdown(z), pushdown(y), pushdown(x);
ll a = z-> son[0] == y ? 0 : 1;
ll b = y-> son[0] == x ? 0 : 1;
if(a == b) rotate(y, a), rotate(x, b);
else rotate(x, b), rotate(x, a);
}
}
} void access(ll cur) {
node* x = e + cur; pushdown(x);
node* y; splay(x, NULL);
if(x-> son[1]) x-> son[1]-> p = cur, x-> son[1]-> fa = NULL, x-> son[1] = NULL;
update(x);
ll pp;
while((pp = x-> p)) {
y = e + pp;
splay(y, NULL);
if(y-> son[1]) y-> son[1]-> p = pp, y-> son[1]-> fa = NULL, y-> son[1] = NULL;
y-> son[1] = x;
x-> fa = y;
update(y);
splay(x, NULL);
}
} void reserve(ll x) {
access(x);
//test(x + e); cout << endl;
(e + x)-> lr ^= 1;
} ll n, m; void link(ll a, ll b) {
access(a);
reserve(b);
(e + b)-> p = a;
update(e + a), update(e + b);
} void cut(ll a, ll b) {
reserve(a), access(b);
//test(b + e); cout << endl;
(e + a)-> p = 0, (e + a)-> fa = NULL, (e + b)-> son[0] = NULL;
update(e + a), update(e + b);
} ll ll_get() {
ll x = 0; char c = (char)getchar();
while(!isdigit(c) && c != '-') c = (char)getchar();
bool f = 0; if(c == '-') f = 1, c = (char)getchar();
while(isdigit(c)) {
x = x * 10 + (ll)(c - '0');
c = (char)getchar();
}
if(f) x = -x;
return x;
} struct edge {
ll t; edge* next;
}se[maxn * 2], *head[maxn]; ll oe = 0; void addedge(ll f, ll t) {
se[oe].t = t, se[oe].next = head[f], head[f] = se + oe ++;
} bool vis[maxn]; void build(ll x, ll pre) {
vis[x] = 1;
(e + x)-> p = pre; (e + x)-> data = (e + x)-> ans = 1; (e + x)-> size = 1; (e + x)-> lm = 1;
for(edge* p = head[x]; p; p = p-> next) {
if(!vis[p-> t]) build(p-> t, x);
}
} void read() {
n = ll_get(), m = ll_get();
for(ll i = 1; i < n; ++ i) {
ll f = ll_get(), t = ll_get();
addedge(f, t), addedge(t, f);
}
memset(vis, 0, sizeof(vis));
build(1, 0);
} void sov() {
char s[10];
// for(int i = 1; i <= n; ++ i) test(e + i), cout << endl;
//cout << "****\n";
while(m --) {
scanf("%s", s + 1);
if(s[1] == '+') {
ll a = ll_get(), b = ll_get(), c = ll_get();
reserve(a); access(b);
node* x = (e + b);
x-> lp = pl(c, x-> lp), x-> ans = pl(x-> ans, mul(c, x-> size)), x-> data = pl(x-> data, c);
}
if(s[1] == '*') {
ll a = ll_get(), b = ll_get(), c = ll_get();
reserve(a);
access(b);
node* x = (e + b);
x-> lm = mul(x-> lm, c), x-> ans = mul(x-> ans, c), x-> data = mul(x-> data, c), x-> lp = mul(x-> lp, c);
}
if(s[1] == '-') {
ll a, b, c, d; a = ll_get(), b = ll_get(), c = ll_get(), d = ll_get();
cut(a, b);
//for(int i = 1; i <= n; ++ i) cout << (e + i)-> p << endl<< endl;
//for(int i = 1; i <= n; ++ i) test(e + i), cout << endl;
//cout << "****\n";
link(c, d); //for(int i = 1; i <= n; ++ i) test(e + i), cout << endl; }
if(s[1] == '/') {
ll a, b; a = ll_get(), b = ll_get();
reserve(a), access(b);
printf("%lld\n", (e + b)-> ans);
}
//for(int i = 1; i <= n; ++ i) test(e + i), cout << endl;
//cout << "****\n";
//cout << (e + 1)-> son[0] << endl;
}
} int main() {
//freopen("test.in", "r", stdin);
//freopen("test.out", "w", stdout);
read();
sov();
}

bzoj 2631的更多相关文章

  1. [BZOJ - 2631] tree 【LCT】

    题目链接:BZOJ - 2631 题目分析 LCT,像线段树区间乘,区间加那样打标记. 这道题我调了一下午. 提交之后TLE了,我一直以为是写错了导致了死循环. 于是一直在排查错误.直到.. 直到我看 ...

  2. bzoj 2631: tree 动态树+常数优化

    2631: tree Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1716  Solved: 576[Submit][Status] Descrip ...

  3. BZOJ 2631: tree( LCT )

    LCT...略麻烦... -------------------------------------------------------------------------------- #inclu ...

  4. BZOJ 2631: tree [LCT splay区间]

    2631: tree Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 3854  Solved: 1292[Submit][Status][Discus ...

  5. BZOJ 2631 tree(动态树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2631 [题目大意] 要求支持链修改,链查询,边断开,连接操作 [题解] 链修改分乘和加 ...

  6. BZOJ 2631 [国家集训队]Tree II (LCT)

    题目大意:给你一棵树,让你维护一个数据结构,支持 边的断,连 树链上所有点点权加上某个值 树链上所有点点权乘上某个值 求树链所有点点权和 (辣鸡bzoj又是土豪题,洛谷P1501传送门) LCT裸题, ...

  7. BZOJ 2631 Tree ——Link-Cut Tree

    [题目分析] 又一道LCT的题目,LCT只能维护链上的信息. [代码] #include <cstdio> #include <cstring> #include <cs ...

  8. [BZOJ 2631]tree

    裸LCT..QAQ写了三遍没写对 真是老了..QAQ 主要错的地方是 init: size[i] = sum[i] = val[i] = mul[i] = 1; pushdown: 注意判断左右儿子是 ...

  9. bzoj 2631: tree link-cut-tree

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

  10. 洛谷 1501 [国家集训队]Tree II BZOJ 2631 Tree

    [题解] 维护乘法标记和加法标记的LCT #include<cstdio> #include<algorithm> #define Mod (51061) #define N ...

随机推荐

  1. 【leetcode】991. Broken Calculator

    题目如下: On a broken calculator that has a number showing on its display, we can perform two operations ...

  2. Django基础--Django基本命令、路由配置系统(URLconf)、编写视图、Template、数据库与ORM

    web框架 框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构. 使用框架可以帮你快速开发特定的系统. 简单地说,就是你用别人搭建好的舞台来做表演. 尝试搭建一个简单 ...

  3. 复位和时钟控制(RCC)

    一.系统复位 复位除了部分RCC寄存器和备份区域以外的其他所有的寄存器: 来源: NRST引脚上的低电平(外部复位) WWDG计数结束 IWDG计数结束 软件复位(通过NVIC) 低电压管理的复位 电 ...

  4. STM32的结构和启动模式

    一.STM32F10x功能模块 32位的Cortex-M3微处理器: 可嵌套的向量中断控制器(NVIC)和60个可屏蔽中断且有16个可编程优先级: 内嵌内存: FLASH:最大512K字节 STAM: ...

  5. 2018icpc沈阳/gym101955 J How Much Memory Your Code Is Using? 签到

    题意: 给你定义一堆变量,计算一下这些变量共占了多少k内存. 题解: 按题意模拟即可,善用ceil() // // Created by melon on 2019/10/22. // #includ ...

  6. System.IO.Path 文件名、路径、扩展名处理

    string filePath =@"E:/Randy0528/中文目录/JustTest.rar"; 更改路径字符串的扩展名.System.IO.Path.ChangeExten ...

  7. margin 负值问题

    * margin-top 和 margin-left 负值,自身元素向上.向左移动: * margin-right 负值,右侧元素左移,自身元素不受影响: * margin-bottom 负值,下方元 ...

  8. Redis 单机模式,主从模式,哨兵模式(sentinel),集群模式(cluster),第三方模式优缺点分析

    Redis 的几种常见使用方式包括: 单机模式 主从模式 哨兵模式(sentinel) 集群模式(cluster) 第三方模式 单机模式 Redis 单副本,采用单个 Redis 节点部署架构,没有备 ...

  9. HDU 3746 Cyclic Nacklace (KMP找循环节)

    题目链接:HDU 3746 Sample Input 3 aaa abca abcde Sample Output 0 2 5 Author possessor WC Source HDU 3rd & ...

  10. 【react】---react中key值的作用

    一.React中key值得作用 react中的key属性,它是一个特殊的属性,它是出现不是给开发者用的,而是给React自己使用,有了key属性后,就可以与组件建立了一种对应关系,简单说,react利 ...