裸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;
}

最新文章

  1. windows 64位 dll文件 位置及python包rtree shapely安装
  2. EL表达式 (详解)(转)
  3. C#基础——Func和Action的介绍及其用法
  4. Core Java Interview Question Answer
  5. Linux 系统下原版 texlive 2016 的安装与配置
  6. bzoj1263
  7. 字符编码笔记:ASCII,Unicode和UTF-8,附带 Little endian和Big endian的解释
  8. 【HDOJ】2510 符号三角形
  9. 万事开头难,用HTML写的第一个界面,收获颇多
  10. hive:条件判断函数
  11. python__基础 : 类的__init__,__str__,__del__方法
  12. appium + java + WebDriverAgent实现IOS app启动
  13. 一个前端开发者换电脑的过程(git篇)
  14. rest-framework序列化
  15. 学习笔记54—均方误差(MSE)和均方根误差(RMSE)和平均绝对误差(MAE)
  16. 什么是 PWA?
  17. crm 任务 状态
  18. HTTP协议图示详解
  19. Blktrace原理简介及使用
  20. UITapGestureRecognizer 的用法(轻触手势识别器)

热门文章

  1. java调用matlab函数
  2. 简单的2d图形变换--仿设变换AffineTransform
  3. codeforces B. Color the Fence 解题报告
  4. July 21st, Week 30th Thursday, 2016
  5. WebStorm设置字体和颜色
  6. WINDOWS xp用户账户怎么没了怎么办?
  7. 转圈游戏(codevs 3285)
  8. Mysql 5.6.17-win64.zip配置
  9. free(): invalid next size (fast/normal)问题
  10. 使用ASP.NET Web API自带的类库实现对CORS的支持(在开发中使用这种方式)(转载)