【以前的空间】link cut tree
这篇文章讲的很好很详细,但是写了几天后发现似乎是挺残的版本。
2049: [Sdoi2008]Cave 洞穴勘测
3282: Tree
2002: [Hnoi2010]Bounce 弹飞绵羊
1036: [ZJOI2008]树的统计Count
都是基础操作吧
后来发现makeroot这个操作可以用个各个地方,改进了一下愉快的切
2631: tree
结果就是tle
结果就是调了两天用了三种lct中splay写法还是tle
结果就是不明白某大神友情提供的代码到底比我的程序优在哪……!
至今还是tle,但是换了几种写法
写法一(自己的程序+各种奇怪的优化+网上大众版splay)
{$M 1000000000,0,maxlongint}
//{$ inline in}
type
arr=record
toward,next:longint;
end;
const
maxn=;
mm=;
var
a:array[..]of longint;
st:string;
fa,q,first,size:array[..maxn]of longint;
sum,mark1,mark2,value:array[..maxn]of qword;
c:array[..maxn,..]of longint;
rev:array[..maxn]of boolean;
edge:array[..maxn*]of arr;
n,m,tot,u,v,j,k,i:longint;
procedure prepare;//inline;
var
i,j,k:longint;
begin
st:=st+' ';
i:=;
j:=;
while i<length(st) do
begin
inc(j); k:=i;
while st[i]<>' ' do inc(i);
val(copy(st,k,i-k),a[j]);
inc(i);
end;
end;
procedure swap(var x,y:longint);//inline;
var
i:longint;
begin
i:=x;
x:=y;
y:=i
end;
function isroot(x:longint):boolean;
begin
if (c[fa[x],]=x) or (c[fa[x],]=x) then exit(True);
exit(false);
end;
procedure update(x:longint);//inline;
begin
sum[x]:=(sum[c[x,]]+sum[c[x,]]+value[x]) mod mm;
size[x]:=size[c[x,]]+size[c[x,]]+;
end;
procedure maintain(x,y,z:longint);//inline;
begin
if x= then exit;
value[x]:=(value[x]*y+z) mod mm;
sum[x]:=(sum[x]*y+z*size[x])mod mm;
mark1[x]:=mark1[x]*y mod mm;
mark2[x]:=(mark2[x]*y+z) mod mm
end;
procedure pushdown(x:longint);//inline;
var
l,r:longint;
begin
if x= then exit;
if rev[x] then begin
swap(c[x,],c[x,]);
rev[c[x,]]:=not rev[c[x,]];
rev[c[x,]]:=not rev[c[x,]];
rev[x]:=false;
end;
if (mark1[x]<>) or (mark2[x]<>) then begin
maintain(c[x,],mark1[x],mark2[x]);
maintain(c[x,],mark1[x],mark2[x]);
mark1[x]:=;
mark2[x]:=;
end
end;
procedure rotate(x:longint);//inline;
var
y,z,l,r:longint;
begin
y:=fa[x];
z:=fa[y];
if c[y,]=x then l:= else l:=;
r:=l xor ;
if isroot(y) then
if c[z,]=y then c[z,]:=x else c[z,]:=x;
fa[x]:=z;
fa[y]:=x;
fa[c[x,r]]:=y;
c[y,l]:=c[x,r];
c[x,r]:=y;
update(y);
//update(x)
end;
procedure splay(x:longint);//inline;
var
top,i,y,z:longint;
begin
top:=;
q[]:=x;
i:=x;
while isroot(i) do begin
inc(top);
q[top]:=fa[i];
i:=fa[i];
end;
for i:=top downto do pushdown(q[i]);
while isroot(x) do begin
y:=fa[x];
z:=fa[y];
if isroot(y) then
if (c[y,]=x) xor (c[z,]=y) then rotate(x)
else rotate(y);
rotate(x);
end
end;
function access(x:longint):longint;//inline;
var
y:longint;
begin
y:=;
repeat
splay(x);
c[x,]:=y;
fa[y]:=x;
update(x);
y:=x;
x:=fa[x];
until x=;
exit(y);
end;
procedure makeroot(x:longint);//inline;
var
y:longint;
begin
y:=access(x);
//splay(x);
rev[y]:=not rev[y];
fa[y]:=;
end;
procedure lct(x1,y1,x2,y2:longint);//inline;
var
y:longint;
begin
makeroot(x1);
access(x1);
y:=y1;
while isroot(y) do y:=fa[y];
fa[y]:=;
y:=x2;
while fa[y]<> do y:=fa[y];
if y<>x1 then swap(x2,y2);
y:=access(y2);
rev[y]:=not rev[y];
fa[y]:=x2
end;
procedure addedge(j,k:longint);//inline;
begin
inc(tot);
edge[tot].toward:=k;
edge[tot].next:=first[j];
first[j]:=tot
end;
procedure dfs(x:longint);//inline;
var
i,too:longint;
begin
i:=first[x];
value[x]:=;
sum[x]:=;
mark1[x]:=;
size[x]:=;
while i<> do begin
too:=edge[i].toward;
if fa[x]<>too then begin
fa[too]:=x;
dfs(too);
end;
i:=edge[i].next;
end
end;
begin
readln(n,m);
for i:= to n- do begin
readln(j,k);
addedge(j,k);
addedge(k,j);
end;
dfs(n>>);
while m> do begin
dec(m);
readln(st);
prepare;
case st[] of
'*':begin
//j:=j mod mm;
makeroot(a[]);
//maintain1(access(a[]),a[]);
maintain(access(a[]),a[],);
end;
'+':begin
//j:=j mod mm;
makeroot(a[]);
//maintain2(access(a[]),a[]);
maintain(access(a[]),,a[]);
end;
'-':lct(a[],a[],a[],a[]);
'/':begin
makeroot(a[]);
writeln(sum[access(a[])]);
end;
end;
end;
end.
写法二(yangzhe大神写法)
type
arr=record
toward,next:longint;
end;
const
maxn=;
mm=;
var
a:array[..]of longint;
st:string;
fa,q,first,size,child:array[..maxn]of longint;
sum,mark1,mark2,value:array[..maxn]of qword;
c:array[..maxn,..]of longint;
rev:array[..maxn]of boolean;
edge:array[..maxn*]of arr;
n,m,tot,u,v,j,k,i:longint;
procedure prepare;
var
i,j,k:longint;
begin
st:=st+' ';
i:=;
j:=;
while i<length(st) do
begin
inc(j); k:=i;
while st[i]<>' ' do inc(i);
val(copy(st,k,i-k),a[j]);
inc(i);
end;
end;
procedure swap(var x,y:longint);
var
i:longint;
begin
i:=x;
x:=y;
y:=i;
end;
procedure update(x:longint);
begin
sum[x]:=(sum[c[x,]]+sum[c[x,]]+value[x]) mod mm;
size[x]:=size[c[x,]]+size[c[x,]]+;
end;
procedure maintain(x,y,z:longint);
begin
if x= then exit;
value[x]:=(value[x]*y+z) mod mm;
sum[x]:=(sum[x]*y+z*size[x])mod mm;
mark1[x]:=mark1[x]*y mod mm;
mark2[x]:=(mark2[x]*y+z) mod mm
end;
procedure pushdown(x:longint);
var
l,r:longint;
begin
if x= then exit;
if rev[x] then begin
child[c[x,]]:=-child[c[x,]];
child[c[x,]]:=-child[c[x,]];
swap(c[x,],c[x,]);
rev[c[x,]]:=not rev[c[x,]];
rev[c[x,]]:=not rev[c[x,]];
rev[x]:=false;
end;
if (mark1[x]<>) or (mark2[x]<>) then begin
maintain(c[x,],mark1[x],mark2[x]);
maintain(c[x,],mark1[x],mark2[x]);
mark1[x]:=;
mark2[x]:=;
end
end;
procedure rotate(node,x:longint);
var
p,y,tmp:longint;
begin
p:=fa[node];
y:=child[p];
tmp:=fa[p];
fa[node]:=tmp;
child[node]:=y;
if y<> then c[tmp,y]:=node;
y:=-x;
tmp:=c[node,y];
c[p,x]:=tmp;
fa[tmp]:=p;
child[tmp]:=x;
fa[p]:=node;
child[p]:=y;
c[node,y]:=p;
update(p);
end;
procedure splay(node:longint);
var
a,p,b,top:longint;
begin
top:=;
q[]:=node;
i:=node;
while child[i]<> do begin
inc(top);
q[top]:=fa[i];
i:=fa[i];
end;
for i:=top downto do pushdown(q[i]);
repeat
a:=child[node];
if a= then break;
p:=fa[node];
b:=child[p];
if a=b then rotate(p,a)
else rotate(node,a);
if b= then break;
rotate(node,b);
until false;
update(node);
end;
function access(x:longint):longint;
var
y:longint;
begin
y:=;
repeat
splay(x);
child[c[x,]]:=;
c[x,]:=y;
fa[y]:=x;
child[y]:=;
update(x);
y:=x;
x:=fa[x];
until x=;
exit(y);
end;
procedure makeroot(x:longint);
var
y:longint;
begin
y:=access(x);
rev[y]:=not rev[y];
fa[y]:=;
child[y]:=;
end;
function getrt(x:longint):longint;
begin
while child[x]<> do x:=fa[x];
exit(x);
end;
function getup(x:longint):longint;
begin
while fa[x]<> do x:=fa[x];
exit(x);
end;
procedure lct(x1,y1,x2,y2:longint);
var
y:longint;
begin
makeroot(y1);
access(y1);
y:=getrt(x1);
fa[y]:=;
child[y]:=;
if getup(x2)<>x1 then swap(x2,y2);
y:=access(y2);
rev[y]:=not rev[y];
fa[y]:=x2;
child[y]:=;
end;
procedure addedge(j,k:longint);
begin
inc(tot);
edge[tot].toward:=k;
edge[tot].next:=first[j];
first[j]:=tot
end;
procedure dfs(x:longint);
var
i,too:longint;
begin
i:=first[x];
value[x]:=;
sum[x]:=;
mark1[x]:=;
size[x]:=;
while i<> do begin
too:=edge[i].toward;
if fa[x]<>too then begin
fa[too]:=x;
child[too]:=;
dfs(too);
end;
i:=edge[i].next;
end
end;
begin
readln(n,m);
for i:= to n- do begin
readln(j,k);
addedge(j,k);
addedge(k,j);
end;
child[n>>]:=;
dfs(n>>);
while m> do begin
dec(m);
readln(st);
prepare;
case st[] of
'*':begin
//j:=j mod mm;
makeroot(a[]);
//maintain1(access(a[]),a[]);
maintain(access(a[]),a[],);
end;
'+':begin
//j:=j mod mm;
makeroot(a[]);
//maintain2(access(a[]),a[]);
maintain(access(a[]),,a[]);
end;
'-':lct(a[],a[],a[],a[]);
'/':begin
makeroot(a[]);
writeln(sum[access(a[])]);
end;
end;
end;
end.
【以前的空间】link cut tree的更多相关文章
- link cut tree 入门
鉴于最近写bzoj还有51nod都出现写不动的现象,决定学习一波厉害的算法/数据结构. link cut tree:研究popoqqq那个神ppt. bzoj1036:维护access操作就可以了. ...
- Codeforces Round #339 (Div. 2) A. Link/Cut Tree 水题
A. Link/Cut Tree 题目连接: http://www.codeforces.com/contest/614/problem/A Description Programmer Rostis ...
- Link/cut Tree
Link/cut Tree 一棵link/cut tree是一种用以表示一个森林,一个有根树集合的数据结构.它提供以下操作: 向森林中加入一棵只有一个点的树. 将一个点及其子树从其所在的树上断开. 将 ...
- 洛谷P3690 Link Cut Tree (模板)
Link Cut Tree 刚开始写了个指针版..调了一天然后放弃了.. 最后还是学了黄学长的板子!! #include <bits/stdc++.h> #define INF 0x3f3 ...
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...
- bzoj2049 [Sdoi2008]Cave 洞穴勘测 link cut tree入门
link cut tree入门题 首先说明本人只会写自底向上的数组版(都说了不写指针.不写自顶向下QAQ……) 突然发现link cut tree不难写... 说一下各个函数作用: bool isro ...
- P3690 【模板】Link Cut Tree (动态树)
P3690 [模板]Link Cut Tree (动态树) 认父不认子的lct 注意:不 要 把 $fa[x]$和$nrt(x)$ 混 在 一 起 ! #include<cstdio> v ...
- Link Cut Tree学习笔记
从这里开始 动态树问题和Link Cut Tree 一些定义 access操作 换根操作 link和cut操作 时间复杂度证明 Link Cut Tree维护链上信息 Link Cut Tree维护子 ...
- [CodeForces - 614A] A - Link/Cut Tree
A - Link/Cut Tree Programmer Rostislav got seriously interested in the Link/Cut Tree data structure, ...
- Link Cut Tree 总结
Link-Cut-Tree Tags:数据结构 ##更好阅读体验:https://www.zybuluo.com/xzyxzy/note/1027479 一.概述 \(LCT\),动态树的一种,又可以 ...
随机推荐
- 相机imu外参标定
1. 第一步初始化imu外参(可以从参数文档中读取,也可以计算出),VINS中处理如下: # Extrinsic parameter between IMU and Camera. estimate_ ...
- 封装Excls数据导出功能 返回一个下载链接地址
/// <summary> /// 获取本地存储地址 /// </summary> /// <param name="dt"></para ...
- spring源码-bean之初始化-1
一.spring的IOC控制反转:控制反转——Spring通过一种称作控制反转(IOC)的技术促进了松耦合.当应用了IOC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查 ...
- Python 获取windows管理员权限办法
from __future__ import print_function import ctypes, sys, os def is_admin(): try: return ctypes.wind ...
- VIM第七版
ZZ:退出并保存 e!:退回到上次保存时的样子 cw:修改单词(自动进入插入模式) cc:修改一整行的内容 cs:修改一个词(自动进入插入模式) .:可以重复上一个命令 J:将下一行内容合并到本行末尾 ...
- 使用分治法求X的N次方,时间效率为lgN
最近在看MIT的算法公开课,讲到分治法的求X的N次方时,只提供了数学思想,于是自己把代码写了下,虽然很简单,还是想动手写一写. int powerN(int x,int n){ if(n==0){ r ...
- OSG的组成结构
OSG的组成结构 核心结构 OSG的功能类采用“命名空间+类名称”的形式来命名.命名空间的命名方式为:第一个单词小写,后继单词的首字母大写,例如osg.osgUtil.osgViewer等:类的名称则 ...
- Android Test和Logcat
一 测试相关概念 是否有源码 黑盒测试: 测试工具 白盒测试: 对所有的源码特别熟悉 对特定的代码进行测试 都是编程 时间 单元测试(程序员) 模块测试 集成测试 系统测试 回归测试(改bug) 压力 ...
- Python文件操作大全
Python 编程文件操作大全 文件打开模式 打开模式 执行操作 'r' 以只读方式打开文件(默认) 'w' 以写入的方式打开文件,会覆盖已存在的文件 'x' 如果文件已经存在,使用此模式打开将引 ...
- servlet和Jsp的复习整理
servlet 1.生命周期 a.构造方法.生成一个servlet b.init()方法.当开启服务器时,servlet第一次被装载,servlet引擎调用这个servlet的init()的方法,只调 ...