【以前的空间】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\),动态树的一种,又可以 ...
随机推荐
- VINS(三)IMU预积分
IMU的数据频率一般远高于视觉,在视觉两帧k,k+1之间通常会有>10组IMU数据.IMU的数据通过积分,可以获取当前位姿(p位置,q四元数表达的姿态).瞬时速度等参数. 在VIO中,如果参考世 ...
- 阅读笔记《JavaScript语言精粹》
阅读笔记<JavaScript语言精粹> 对象 1.检索属性 使用[]和. 2.引用传递 JavaScript的简单数据类型包括数字.字符串.布尔值.null值和undefined值.其它 ...
- VMWare虚拟机下 centos network is unreachable 问题的解决
vi /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 BOOTPROTO=static BROADCAST=192.168.1.255 HW ...
- R语言使用过程中出现的问题--读取EXCEL文件
方法一: 按照R导论中的方法,使用RODBC包, library(RODBC) channel<-odbcConnectExcel("file.xlsx") da2<- ...
- ElasticSearch-Java-low-level-rest-client官方文档翻译
人肉翻译,非谷歌机翻,部分地方添加了个人的理解,并做了分割,如有错误请在评论指出.转载请指明原链接,尊重个人劳动成果. High-Level-Rest-Client基于Low-Level ...
- <cfloat> (float.h)
头文件: <cfloat> (float.h) 浮点类型的特性 这个头文件为特殊系统和编译器的实现描述了浮点类型的特征. 一个浮点数包含四个元素: 一个标志(a sign):正或负; 一个 ...
- "Generative Adversarial Nets" Notes
- Ian J.Goodfellow 中文翻译:https://blog.csdn.net/wspba/article/details/54577236 代码实现:https://github.com ...
- ARM架构中的程序执行与调用
ARM架构中的程序执行与调用 1. 几个名词 ABI : 可执行文件必须遵守的规范,以在特定执行环境中运行: 单独产生的可重定址的文件必须遵守的规范,以用来链接和执行. EABI: 适用于嵌入式环境的 ...
- Python3 Tkinter-Entry
1.创建 from tkinter import * root=Tk() t1=Entry(root) t1.pack() root.mainloop() 2.绑定变量 from tkinter im ...
- var,let,const,三种申明变量的整理
javascript,正在慢慢变成一个工业级语言,势力慢慢渗透ios,安卓,后台 首先let,是局部变量,块级作用域:var全局的,const是常量,也就是只读的: 一行demo说明 for (var ...