BZOJ 3306 树 Link-Cut-Tree+set
2015-09-06 20:54
507 查看
题目大意:给定一棵有根树,每个点有个权值,要求维护换根、单点修改、查询子树最小值
闲得我写了发LCT……
(这段时间咋净写LCT了。。。
每个节点开一个multiset记录一下所有虚边连接的子树的最小值
然后切换虚边的时候把原来的实边连接的子树扔进multiset,把新的实边连接的子树从multiset里删除就行了
时间复杂度O(nlog2n)O(nlog^2n)
闲得我写了发LCT……
(这段时间咋净写LCT了。。。
每个节点开一个multiset记录一下所有虚边连接的子树的最小值
然后切换虚边的时候把原来的实边连接的子树扔进multiset,把新的实边连接的子树从multiset里删除就行了
时间复杂度O(nlog2n)O(nlog^2n)
[code]#include <set> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 100100 using namespace std; int n,m,a[M]; namespace Link_Cut_Tree{ struct abcd{ abcd *ls,*rs,*fa; multiset<int> s; int min_val; bool rev_mark; abcd(int _); void Push_Up(); void Push_Down(); void Reverse(); }*null=new abcd(0x7fffffff),*tree[M]; abcd :: abcd(int _) { ls=rs=fa=null; s.insert(_); min_val=_; rev_mark=false; } void abcd :: Push_Up() { min_val=min(min(ls->min_val,rs->min_val),*(s.begin())); } void abcd :: Push_Down() { if(fa->ls==this||fa->rs==this) fa->Push_Down(); if(rev_mark) { ls->Reverse(); rs->Reverse(); rev_mark=false; } } void abcd :: Reverse() { swap(ls,rs); rev_mark^=1; } void Zig(abcd *x) { abcd *y=x->fa; y->ls=x->rs; x->rs->fa=y; x->rs=y; x->fa=y->fa; if(y==y->fa->ls) y->fa->ls=x; else if(y==y->fa->rs) y->fa->rs=x; y->fa=x; y->Push_Up(); } void Zag(abcd *x) { abcd *y=x->fa; y->rs=x->ls; x->ls->fa=y; x->ls=y; x->fa=y->fa; if(y==y->fa->ls) y->fa->ls=x; else if(y==y->fa->rs) y->fa->rs=x; y->fa=x; y->Push_Up(); } void Splay(abcd *x) { x->Push_Down(); while(x->fa->ls==x||x->fa->rs==x) { abcd *y=x->fa,*z=y->fa; if(x==y->ls) { if(y==z->ls) Zig(y); Zig(x); } else { if(y==z->rs) Zag(y); Zag(x); } } x->Push_Up(); } void Access(abcd *x) { abcd *y=null; while(x!=null) { Splay(x); if(x->rs!=null) x->s.insert(x->rs->min_val); x->rs=y; if(y!=null) x->s.erase(x->s.find(y->min_val)); x->Push_Up(); y=x;x=x->fa; } } void Move_To_Root(abcd *x) { Access(x); Splay(x); x->Reverse(); } } struct edge{ int to,next; }table[M<<1]; int head[M],tot; void Add(int x,int y) { table[++tot].to=y; table[tot].next=head[x]; head[x]=tot; } void DFS(int x) { using namespace Link_Cut_Tree; int i; tree[x]=new abcd(a[x]); for(i=head[x];i;i=table[i].next) { DFS(table[i].to); tree[table[i].to]->fa=tree[x]; tree[x]->s.insert(tree[table[i].to]->min_val); } tree[x]->Push_Up(); } int main() { using namespace Link_Cut_Tree; int i,x,y; char p[10]; cin>>n>>m; for(i=1;i<=n;i++) { scanf("%d%d",&x,&a[i]); if(x) Add(x,i); } DFS(1); for(i=1;i<=m;i++) { scanf("%s",p); if(p[0]=='V') { scanf("%d%d",&x,&y); Access(tree[x]); Splay(tree[x]); tree[x]->s.erase(tree[x]->s.find(a[x])); a[x]=y; tree[x]->s.insert(a[x]); tree[x]->Push_Up(); } else if(p[0]=='E') { scanf("%d",&x); Move_To_Root(tree[x]); } else { scanf("%d",&x); Access(tree[x]); Splay(tree[x]); printf("%d\n",*(tree[x]->s.begin())); } } return 0; }
相关文章推荐
- HttpUrlConnection下载cookie与访问时需要附带cookie的预留
- 直接插入排序法——java语言实现
- 上层建筑——DOM元素的特性与属性(dojo/dom-attr)
- 苹果API常用英语名词
- UIActivityIndicatorView
- 第二章 链路层
- [概念]MD5算法
- Mail、计划任务
- 设计模式之抽象工厂模式
- 3MQ-2烟雾传感器
- LeetCode题解:Construct Binary Tree from Preorder and Inorder Traversal
- 170 网络的可靠性【连通】
- 15/9/6/Fragment
- [MFC]在程序中访问对话框中的控件——GetDlgItem函数
- backtrack环境的基本配置之网络配置基本命令
- MyBatis 环境搭建 (一)
- 跟马哥学linux (lesson 5)linux任务管理
- 黑马程序员之网络编程
- (2015秋) 作业1:学生调研(总分10分)
- 摄像机模型与标定—棋盘、亚像素角点和绘制棋盘角点