您的位置:首页 > 其它

Link-Cut-Tree题目泛做(为了对应自己的课件)

2016-01-27 20:55 387 查看
题目1:BZOJ 2049 洞穴勘测

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#define L(x) c[x][0]
#define R(x) c[x][1]

using namespace std;

const int N = 300000 + 5;
const int oo = 0x3f3f3f3f;

int n, m, tot;
int first
, nxt[N<<1];
int u[N<<1], v[N<<1];
int que[N<<1];

struct SplayTree{
int fa
, c
[2], val
, mx
, add
;
bool rev
;
int top, st
;

inline bool isroot(int x){
return L(fa[x]) != x && R(fa[x]) != x;
}

void pushup(int x){
int l = L(x), r = R(x);

mx[x] = max(mx[l], mx[r]);
mx[x] = max(mx[x], val[x]);
}

void pushdown(int x){
int l = L(x), r = R(x);

if(rev[x]){
rev[x] ^= 1; rev[l] ^= 1; rev[r] ^= 1;
swap(L(x), R(x));
}
if(add[x]){
if(l){
add[l] += add[x]; mx[l] += add[x]; val[l] += add[x];
}
if(r){
add[r] += add[x]; mx[r] += add[x]; val[r] += add[x];
}
add[x] = 0;
}
}

void rotate(int x){
int y = fa[x], z = fa[y], l, r;

l = (L(y) == x) ^ 1; r = l ^ 1;
if(!isroot(y)){
c[z][L(z) == y ^ 1] = x;
}
fa[x] = z; fa[y] = x; fa[c[x][r]] = y;
c[y][l] = c[x][r]; c[x][r] = y;
pushup(y); pushup(x);
}

void splay(int x){
top = 0;
st[++ top] = x;
for(int i = x; !isroot(i); i = fa[i])
st[++ top] = fa[i];
while(top) pushdown(st[top --]);
while(!isroot(x)){
int y = fa[x], z = fa[y];

if(!isroot(y)){
if(L(y) == x ^ L(z) == y) rotate(x);
else rotate(y);
}
rotate(x);
}
}
}Splay;

struct LinkCutTree{
void Access(int x){
int t = 0;

while(x){
Splay.splay(x);
Splay.R(x) = t;
t = x;
Splay.pushup(x);
x = Splay.fa[x];
}
}
void Add(int x, int y, int w){
makeroot(x); Access(y); Splay.splay(y);
Splay.add[y] += w; Splay.val[y] += w;
Splay.mx[y] += w;
}
int findroot(int x){
Access(x); Splay.splay(x);

int y = x;

while(Splay.L(y)){
y = Splay.L(y);
}

return y;
}

void makeroot(int x){
Access(x); Splay.splay(x); Splay.rev[x] ^= 1;
}

void cut(int x, int y){
makeroot(x); Access(y); Splay.splay(y);
Splay.L(y) = Splay.fa[Splay.L(y)] = 0; Splay.pushup(y);
}

void link(int x, int y){
makeroot(x); Splay.fa[x] = y; Splay.splay(x);
}
}lct;

void insert(int s, int t){
++ tot;
u[tot] = s; v[tot] = t;
nxt[tot] = first[s];
first[s] = tot;
}

void bfs(){
int head, tail;
head = tail = 1;
que[head] = 1;
Splay.fa[1] = 0;

while(head <= tail){
int x = que[head];

for(int i = first[x]; i; i = nxt[i]){
if(v[i] != Splay.fa[x]){
Splay.fa[v[i]] = x;
que[++ tail] = v[i];
}
}
++ head;
}
}

int main(){
int flag, x, y, z;

while(~scanf("%d", &n)){
tot = 0;
for(int i = 0; i <= n; ++ i){
Splay.fa[i] = Splay.val[i] = Splay.add[i] = 0;
Splay.rev[i] = false;
Splay.mx[i] = -oo;
Splay.c[i][0] = Splay.c[i][1] = 0;
first[i] = 0;
}
for(int i = 1; i < n; ++ i){
scanf("%d%d", &x, &y);
insert(x, y); insert(y, x);
}
for(int i = 1; i <= n; ++ i){
scanf("%d", &x);
Splay.val[i] = Splay.mx[i] = x;
}
bfs();

scanf("%d", &m);
for(int i = 1; i <= m; ++ i){
scanf("%d", &flag);
switch(flag){
case 1:{
scanf("%d%d", &x, &y);
if(lct.findroot(x) == lct.findroot(y))
puts("-1");
else
lct.link(x, y);
break;
}
case 2:{
scanf("%d%d", &x, &y);
if(lct.findroot(x) != lct.findroot(y) || x == y)
puts("-1");
else lct.cut(x, y);
break;
}
case 3:{
scanf("%d%d%d", &z, &x, &y);
if(lct.findroot(x) != lct.findroot(y))
puts("-1");
else
lct.Add(x, y, z);
break;
}
case 4:{
scanf("%d%d", &x, &y);
if(lct.findroot(x) != lct.findroot(y))
puts("-1");
else{
lct.makeroot(x); lct.Access(y); Splay.splay(y);
printf("%d\n", Splay.mx[y]);
}
break;
}
}
}
puts("");
}

return 0;
}


HDU 4010
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: