[BZOJ 2631]tree
裸LCT。。QAQ写了三遍没写对
真是老了。。QAQ
主要错的地方是
init:
size[i] = sum[i] = val[i] = mul[i] = 1;
pushdown:
注意判断左右儿子是否为空
splay:
前面有pushdown, stack..
while(!isroot(p)){
int x = fa[p], y = fa[x];
if(!isroot(x))...
}
Access:
while(u){
...
c[u][] = t;
u = fa[u];
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 100010
using namespace std; typedef long long ll; const int md = 51061; int n, q;
int c[maxn][2], fa[maxn], val[maxn], mul[maxn], add[maxn];
int sum[maxn], top, st[maxn], size[maxn];
bool rev[maxn];
namespace splay{
inline void Mul(int& x, ll y){
x = x * y % md;
}
inline void Add(int& x, ll y){
x = (x + y) % md;
} void init(){
for(int i = 1; i <= n; i ++)
val[i] = mul[i] = 1, add[i] = 0;
} inline void pushup(int x){
sum[x] = (sum[c[x][0]] + sum[c[x][1]] + val[x]) % md;
size[x] = size[c[x][0]] + size[c[x][1]] + 1;
} inline void pushdown(int x){
if(rev[x]){
if(c[x][0])rev[c[x][0]] ^= 1;
if(c[x][1])rev[c[x][1]] ^= 1;
swap(c[x][0], c[x][1]);
rev[x] = 0;
} int lc = c[x][0], rc = c[x][1];
if(lc != 0){
if(mul[x] != 1){
Mul(mul[lc], mul[x]);
Mul(add[lc], mul[x]);
Mul(val[lc], mul[x]);
Mul(sum[lc], mul[x]);
}
if(add[x] != 0){
Add(add[lc], add[x]);
Add(val[lc], add[x]);
Add(sum[lc], (ll)size[lc] * add[x]);
}
} if(rc != 0){
if(mul[x] != 1){
Mul(mul[rc], mul[x]);
Mul(add[rc], mul[x]);
Mul(val[rc], mul[x]);
Mul(sum[rc], mul[x]);
}
if(add[x] != 0){
Add(add[rc], add[x]);
Add(val[rc], add[x]);
Add(sum[rc], (ll)size[rc] * add[x]);
}
}
mul[x] = 1, add[x] = 0;
} inline bool isroot(int x){
return c[fa[x]][0] != x && c[fa[x]][1] != x;
} inline void rotate(int p, int x){
int mark = p == c[x][1], y = c[p][mark^1], z = fa[x];
if(c[z][0] == x) c[z][0] = p;
if(c[z][1] == x) c[z][1] = p;
if(y) fa[y] = x;
c[p][mark^1] = x, fa[p] = z;
c[x][mark] = y, fa[x] = p;
pushup(x);
} inline void splay(int p){
st[top = 1] = p;
for(int i = p; !isroot(i); i = fa[i])
st[++ top] = fa[i];
while(top) pushdown(st[top --]);
while(!isroot(p)){
int x = fa[p], y = fa[x];
if(isroot(x))rotate(p, x);
else if(p == c[x][0] ^ x == c[y][0])
rotate(p, x), rotate(p, y);
else rotate(x, y), rotate(p, x);
}
pushup(p);
} inline void update(int x, int mu, int ad){
if(mu != 1){
Mul(val[x], mu);
Mul(mul[x], mu);
Mul(add[x], mu);
Mul(sum[x], mu);
} if(ad != 0){
Add(val[x], ad);
Add(add[x], ad);
Add(sum[x], (ll)size[x] * ad);
}
}
} namespace LCT{
void Access(int u){
int t = 0;
while(u){
splay::splay(u);
c[u][1] = t;
t = u;
splay::pushup(u);
u = fa[u];
}
} void Evert(int u){
Access(u);
splay::splay(u);
rev[u] ^= 1;
splay::pushdown(u);
} void link(int u, int v){
Evert(u);
fa[u] = v;
//Access(u); splay::splay(u);
} void cut(int u, int v){
Evert(u);
Access(v);
splay::splay(v);
c[v][0] = fa[u] = 0;
splay::pushup(v);
} void update(int u, int v, int mu, int ad){
Evert(u), Access(v);
splay::splay(v);
splay::update(v, mu, ad);
} int ask(int u, int v){
Evert(u), Access(v);
splay::splay(v);
return sum[v];
}
} int main(){
scanf("%d%d", &n, &q);
splay::init();
int u, v, u1, v1, c;
for(int i = 1; i < n; i ++){
scanf("%d%d", &u, &v);
LCT::link(u, v);
}
for(int i = 1; i <= q; i ++){
char ch = getchar();
for(; ch < '!'; ch = getchar());
if(ch == '+'){
scanf("%d%d%d", &u, &v, &c);
LCT::update(u, v, 1, c);
}
if(ch == '-'){
scanf("%d%d%d%d", &u, &v, &u1, &v1);
LCT::cut(u, v);
LCT::link(u1, v1);
}
if(ch == '*'){
scanf("%d%d%d", &u, &v, &c);
LCT::update(u, v, c, 0);
}
if(ch == '/'){
scanf("%d%d", &u, &v);
printf("%d\n", LCT::ask(u, v));
}
}
return 0;
}
[BZOJ 2631]tree的更多相关文章
- bzoj 2631: tree 动态树+常数优化
2631: tree Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1716 Solved: 576[Submit][Status] Descrip ...
- [BZOJ - 2631] tree 【LCT】
题目链接:BZOJ - 2631 题目分析 LCT,像线段树区间乘,区间加那样打标记. 这道题我调了一下午. 提交之后TLE了,我一直以为是写错了导致了死循环. 于是一直在排查错误.直到.. 直到我看 ...
- BZOJ 2631: tree( LCT )
LCT...略麻烦... -------------------------------------------------------------------------------- #inclu ...
- BZOJ 2631: tree [LCT splay区间]
2631: tree Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 3854 Solved: 1292[Submit][Status][Discus ...
- BZOJ 2631 tree(动态树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2631 [题目大意] 要求支持链修改,链查询,边断开,连接操作 [题解] 链修改分乘和加 ...
- BZOJ 2631 tree 动态树(Link-Cut-Tree)
题目大意:维护一种树形数据结构.支持下面操作: 1.树上两点之间的点权值+k. 2.删除一条边.添加一条边,保证加边之后还是一棵树. 3.树上两点之间点权值*k. 4.询问树上两点时间点的权值和. 思 ...
- BZOJ 2631 Tree ——Link-Cut Tree
[题目分析] 又一道LCT的题目,LCT只能维护链上的信息. [代码] #include <cstdio> #include <cstring> #include <cs ...
- bzoj 2631: tree link-cut-tree
题目: Description 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u ...
- 洛谷 1501 [国家集训队]Tree II BZOJ 2631 Tree
[题解] 维护乘法标记和加法标记的LCT #include<cstdio> #include<algorithm> #define Mod (51061) #define N ...
随机推荐
- ethtool 命令详解
命令描述: ethtool 是用于查询及设置网卡参数的命令. 使用概要:ethtool ethx //查询ethx网口基本设置,其中 x 是对应网卡的编号,如eth0.eth1等等 转自: ...
- petri网学习心得
本文转载自duxw,如给您带来不便之处,请联系博主. 1.Petri网书籍:<petri网导论>,吴哲辉 非常适合初学者.概念清晰,容易理解. 2.工作流书籍:<Workflow M ...
- 编译安装0bda 8179无线网卡
CentOS下安装USB无线网卡(Obda:8179) 参考:http://blog.163.com/thinki_cao/blog/static/83944875201311593529913/ c ...
- 2013 ACM/ICPC 长春网络赛F题
题意:两个人轮流说数字,第一个人可以说区间[1~k]中的一个,之后每次每人都可以说一个比前一个人所说数字大一点的数字,相邻两次数字只差在区间[1~k].谁先>=N,谁输.问最后是第一个人赢还是第 ...
- mysql 判空
2013年9月10日 15:44:36 update `zzb_table` set status = 1 where `link` != ''; 不要用 update `zzb_table` set ...
- hdu 1160 FatMouse's Speed 解题报告
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1160 题目意思:给出一堆老鼠,假设有 n 只(输入n条信息后Ctrl+Z).每只老鼠有对应的weigh ...
- Android中如何让手机屏幕不待机
在Android中,申请WakeLock可以让你的进程持续执行即使手机进入睡眠模式,比较实用的是比如后台有网络功能,可以保证操作持续进行. 方法: 在操作之前加入 PowerManager pm = ...
- 【读书笔记】读《JavaScript高级程序设计-第2版》 - 函数部分
1. 定义 函数实际上是对象,每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法.由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定. 对于函数 ...
- 运行基准测试hadoop集群中的问题:org.apache.hadoop.ipc.RemoteException: java.io.IOException: File /benchmarks/TestDFSIO/io_data/test_
在master(即:host2)中执行 hadoop jar hadoop-test-1.1.2.jar DFSCIOTest -write -nrFiles 12 -fileSize 10240 - ...
- 大白菜U盘启动盘制作工具V5.0如何制作启动系统U盘
1:切换到ISO模式或者直接点击主程序左上角的ISO制作,程序会切换到ISO制作界面. 2:在路径里选好ios文件,点击按钮. 3:打开ISO模式的一键制作启动U盘,点击ISO模式里的按钮,按照图中推 ...