BZOJ 2959 长跑 Link-Cut-Tree+并查集
来源:互联网 发布:什么软件,歌很全 编辑:程序博客网 时间:2024/04/29 03:00
题目大意:给定n个点,支持以下操作:
1.在某两个点之间连接一条无向边
2.改变某个点的权值
3.将每条边设定一个方向,然后从
首先如果这个图是静态的,我们把边双都缩点,那么每次询问显然就是两个点所在边双路径上的点权和
现在图是动态的,因此我们用动态树维护一下就行了
如果连边的两个点不连通,就在LCT中连接这两个点
如果连边的两个点已经连通,就将这个两个点路径上的所有点用并查集缩点
时间复杂度
似乎用链剖会快一些?
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define M 150100using namespace std;int n,m;int a[M];struct Union_Find_Set{ int fa[M]; int Find(int x) { if(!fa[x]||fa[x]==x) return fa[x]=x; return fa[x]=Find(fa[x]); } void Union(int x,int y) { x=Find(x);y=Find(y); if(x==y) return ; fa[x]=y; }}s1,s2;namespace Link_Cut_Tree{ struct abcd{ abcd *ls,*rs,*fa; int val,sum; bool rev_mark; abcd() {} abcd(int x); void Push_Up(); void Push_Down(); void Reverse(); }tree[M],*null=&tree[0]; abcd :: abcd(int x) { ls=rs=fa=null; val=sum=x; rev_mark=false; } void abcd :: Push_Up() { sum=ls->sum+rs->sum+val; } 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); x->rs=y; x->Push_Up(); x->fa=&tree[s2.Find(x->fa-tree)]; y=x;x=x->fa; } } void Move_To_Root(abcd *x) { Access(x); Splay(x); x->Reverse(); } void Link(abcd *x,abcd *y) { Move_To_Root(x); x->fa=y; } void Reduction(abcd *&x,abcd *y) { if(x==null) return ; s2.Union(x-tree,y-tree); y->val+=x->val; Reduction(x->ls,y); Reduction(x->rs,y); x=null; }}namespace IStream{ #define L (1<<16) char Get_Char() { static char buffer[M],*S,*T; if(S==T) { T=(S=buffer)+fread(buffer,1,L,stdin); if(S==T) return EOF; } return *S++; } int Get_Int() { int re=0; char c=Get_Char(); while(c<'0'||c>'9') c=Get_Char(); while(c>='0'&&c<='9') re=(re<<3)+(re<<1)+(c-'0'),c=Get_Char(); return re; }}int main(){ using namespace Link_Cut_Tree; using namespace IStream; int i,p,x,y; cin>>n>>m; for(i=1;i<=n;i++) { a[i]=Get_Int(); tree[i]=abcd(a[i]); } for(i=1;i<=m;i++) { p=Get_Int(); x=Get_Int(); y=Get_Int(); if(p==1) { x=s2.Find(x);y=s2.Find(y); if(x==y) continue ; if(s1.Find(x)!=s1.Find(y)) Link(&tree[x],&tree[y]),s1.Union(x,y); else { Move_To_Root(&tree[x]); Access(&tree[y]); Splay(&tree[y]); Reduction(tree[y].ls,&tree[y]); Reduction(tree[y].rs,&tree[y]); tree[y].Push_Up(); } } else if(p==2) { Splay(&tree[s2.Find(x)]); tree[s2.Find(x)].val+=y-a[x]; tree[s2.Find(x)].Push_Up(); a[x]=y; } else { x=s2.Find(x);y=s2.Find(y); if(s1.Find(x)!=s1.Find(y)) puts("-1"); else { Move_To_Root(&tree[x]); Access(&tree[y]); Splay(&tree[y]); printf("%d\n",tree[y].sum); } } } return 0;}
1 0
- BZOJ 2959 长跑 Link-Cut-Tree+并查集
- BZOJ 2959: 长跑(LCT+并查集)
- bzoj 2959: 长跑 lct+并查集
- bzoj 2959: 长跑(LCT+并查集)
- [bzoj3664][Noi2014]魔法森林 Link-Cut-Tree 并查集
- 2959: 长跑|LCT+并查集
- bzoj 2049(link cut tree)
- bzoj 2157(link cut tree)
- bzoj 1180(link cut tree)
- bzoj 2631(link cut tree)
- BZOJ 2002 Link-Cut Tree
- BZOJ 2631 Tree Link-Cut-Tree(LCT)
- BZOJ 3282 Tree Link-Cut-Tree(LCT)
- BZOJ-2631 tree Link-Cut-Tree
- bzoj 2631 Tree [Link-Cut Tree]
- BZOJ 2631 tree Link Cut Tree
- BZOJ 1180 CROATIAN2009 OTOCI Link-Cut-Tree
- BZOJ 3091 城市旅行 Link-Cut-Tree
- C/C++基本数据类型所占字节数
- js中的getAttribute()方法
- 数学基础知识及函数
- Axis2创建webservice实例
- 浅析iOS程序设计模式(基于MVC)
- BZOJ 2959 长跑 Link-Cut-Tree+并查集
- AFNetworking error - 1005
- IDR、CRA、BLA、RASL、RADL、closed-gop、open-gop
- In-App Purchase相关资料
- linux下IPTABLES配置详解
- vs2010 问题 >LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
- 不使用 +-×÷ 运算符来实现 加减乘除 四项运算
- #笔记#圣思园 JavaSE 第44讲——栈、队列
- Python:编写函数,能在当前目录以及子目录下查找文件名包含指定字符串的文件,并打印出完整路径