您的位置:首页 > 其它

LCT 动态树 hdu 5002

2016-03-11 16:44 337 查看
LCT的模板题,当做是学了一个模板
#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 111111;
int m,n;
class LCT
{
private:
struct node
{
int size,same,rev,val,inc;
pair<int,int> value[2];
node *ch[2],*f;
bool isroot;
inline void setchild(node *tmp,int dir)
{
ch[dir] = tmp;
tmp->f = this;
}
inline int isrc()
{
return f->ch[1] == this;
}
int calc(int v)
{
int res = 0;
if(val == v)
res++;
for(int i = 0;i < 2;i++)
{
for(int j = 0;j < 2;j++)
{
if(this->ch[i]->value[j].first == v)
{
res+= this ->ch[i] ->value[j].second;
}
}
}
return res;
}
inline void update()
{
if(size == 0)
{
return ;
}
int maxvalue = max(max(ch[0]->value[0].first,ch[1]->value[0].first),val);
value[0] = make_pair(maxvalue,this->calc(maxvalue));
int sec = -INF;
if(val != maxvalue)
{
sec = max(sec,val);
}
for(int i = 0;i < 2;i++)
{
for(int j = 0;j < 2;j++)
{
if(this -> ch[i] ->value[j].first!=maxvalue)
{
sec = max(sec,this->ch[i] -> value[j].first);
}
}
}
value[1] = make_pair(sec,this->calc(sec));
size = 1 + ch[0]->size + ch[1] -> size;
}
inline void make(int v)
{
if(size == 0)
{
return ;
}
value[0] = make_pair(v,size);

value[1] = make_pair(-INF,0);
same = v;
inc = 0;
val = v;
}
inline void add(int v)
{
if(size == 0)
return ;
inc+=v;
val+=v;
if(value[0].first != -INF)
{
value[0].first+= v;
}
if(value[1].first != -INF)
{
value[1].first+=v;
}
}
inline void reverse()
{
if(size == 0)
return ;
rev^=1;swap(ch[0],ch[1]);
}
inline void push()
{
if(size == 0)
return ;
if(rev)
{
ch[0]->reverse();
ch[1]->reverse();
rev = 0;
}
if(same!=-INF)
{
ch[0]->make(same);
ch[1] -> make(same);
same = -INF;
}
if(inc)
{
ch[0]->add(inc);
ch[1]->add(inc);
inc = 0;
}
}
};
typedef node *Node;
node mem
;
int used;
Node Null,t
;

Node newnode(int v)
{
Node tmp = &mem[used++];
tmp->size = 1;tmp->same = -INF;tmp->rev =0;tmp->val = v;tmp->inc = 0;
tmp->value[0] = make_pair(v,1);
tmp->value[1] = make_pair(-INF,0);
tmp->ch[0] = tmp->ch[1] = tmp->f = Null;
tmp->isroot = true;
return tmp;
}

void rotate(Node root)
{
Node father = root->f;
father->push();root->push();
int dir = root->isrc();
father->setchild(root->ch[!dir],dir);
if(father->isroot)
{
father -> isroot = false;
root->isroot = true;
root -> f = father ->f;
}
else
father->f->setchild(root,father->isrc());
root -> setchild(father,!dir);
father->update();
}
void splay(Node root)
{
for(root -> push();!root->isroot;)
{
if(root->f->isroot)
rotate(root);
else
{
(root -> isrc() == root -> f -> isrc())?(r
4000
otate(root -> f),rotate(root)):(rotate(root),rotate(root));
}
}
root->update();
}
void access(Node root,int oper = 0,int val = 0)
{
for(Node tmp(Null);root!=Null;)
{
splay(root);
if(root->f == Null&&oper)
{
if(oper == 1)
{
tmp->make(val);
root->push();
root ->ch[1]->make(val);
root->val = val;
root->update();
}
if(oper == 2)
{
tmp->add(val);
root -> push();
root->ch[1]->add(val);
root->val+=val;
root->update();
}
}
root->ch[1]->isroot = true;
root->ch[1] = tmp;
root->ch[1] -> isroot = false;
root->update();
tmp = root;
root = root->f;
}
}
public:
void init(int a,int val[])
{
used = 0;
Null = newnode(-INF);
Null->f = Null->ch[0] = Null->ch[1] = Null;
Null -> size = 0;
for(int i = 1;i <= a;i++)
{
t[i] = newnode(val[i]);
}
}
void link(int son,int father)
{
access(t[son]);
splay(t[son]);
t[son] ->f = t[father];
t[son]->reverse();
}
void cut(int u,int v)
{
access(t[v]);
splay(t[u]);
if(t[u]->f == t[v])
{
t[u]->f = Null;
}
else
{
access(t[u]);
splay(t[v]);
if(t[v]->f == t[u])
{
t[v]->f = Null;
}
}
}

void makesame(int u,int v,int val)
{
access(t[u]);
access(t[v],1,val);
}
void add(int u,int v,int val)
{
access(t[u]);
access(t[v],2,val);
}
pair<int,int> getvalue(int u,int v)
{
access(t[u]);
Node root = t[v];
pair<int,int>res;
for(Node tmp(Null);root!=Null;)
{
splay(root);
if(root->f==Null)
{
root->push();
Node a = tmp,b = root->ch[1];
vector<int> vv;
vv.push_back(root->val);
for(int i = 0;i < 2;i++)
{
vv.push_back(a->value[i].first);
vv.push_back(b->value[i].first);
}
sort(vv.begin(),vv.end());
vv.erase(unique(vv.begin(),vv.end()),vv.end());
reverse(vv.begin(),vv.end());
while(vv.size()&&vv.back() == -INF)
{
vv.pop_back();
}
if(vv.size() == 1)
{
res = make_pair(-INF,0);
}
else
{
res =   make_pair(vv[1],0);
for(int i = 0;i < 2;i++)
{
if(a->value[i].first == vv[1])
{
res.second += a->value[i].second;
}
if(b->value[i].first==vv[1])
{
res.second += b->value[i].second;
}
}
res.second+=(root->val == vv[1]);
}
}
root->ch[1]->isroot = true;
root->ch[1] = tmp;
root -> ch[1] -> isroot = false;
root->update();
tmp = root;
root = root -> f;
}
return res;
}
}tree;
int main()
{
int test;
scanf("%d", &test);
while(test--) {
static int testCount = 0;
printf("Case #%d:\n", ++testCount);
scanf("%d %d", &n, &m);
static int val
;
for(int i = 1; i <= n; i++) {
scanf("%d", &val[i]);
}
tree.init(n, val);
for(int i = 1; i < n; i++) {
int a, b;
scanf("%d %d", &a, &b);
tree.link(a, b);
}
for(int i = 1; i <= m; i++) {
int type, a, b, x, y;
scanf("%d", &type);
if (type == 1) {
scanf("%d %d %d %d", &x, &y, &a, &b);
tree.cut(x, y);
tree.link(a, b);
} else if (type == 2) {
scanf("%d %d %d", &a, &b, &x);
tree.makesame(a, b, x);
} else if (type == 3) {
scanf("%d %d %d", &a, &b, &x);
tree.add(a, b, x);
} else {
int a, b;
scanf("%d %d", &a, &b);
pair<int, int> temp = tree.getvalue(a, b);
if (temp.first == -INF) {
printf("ALL SAME\n");
} else {
printf("%d %d\n", temp.first, temp.second);
}
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: