【以前的空间】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\),动态树的一种,又可以 ...
随机推荐
- 关于 Windows 10 字体安装目录的问题
不知从什么时候开始,本人台式机的Win10系统在安装字体的时候并不是安装到C:\Windows\Fonts目录中,而是安装到%USERPROFILE%\AppData\Local\Microsoft\ ...
- MySQL☞upper函数
upper(列名/字符串):把小写字母改为大写字母 格式: select upper(列名/字符串) from 表名 如下图:
- C#冒泡排序法及优化
冒泡排序法及优化: static void Main(string[] args) { , , , , , }; ; //冒泡排序法 ; i < sums.Length - ; i++) //总 ...
- [Clr via C#读书笔记]Cp1CLR执行模型
Cp1CLR执行模型 本章的概念点 CLR=Common Language Runtime 内存管理,程序集加载,安全性,异常处理和线程同步.CLR是基础,支持着面向它的各种语言.各种语言会被对应的编 ...
- TensorFlow入门之MNIST最佳实践-深度学习
在上一篇<TensorFlow入门之MNIST样例代码分析>中,我们讲解了如果来用一个三层全连接网络实现手写数字识别.但是在实际运用中我们需要更有效率,更加灵活的代码.在TensorFlo ...
- ThinkPHP - 5 - 学习笔记(2015.4.15)
ThinkPHP __construct()和__initialize() 1.__initialize()不是php类中的函数,php类的构造函数只有__construct().2.类的初始化:子类 ...
- Python3 数据类型-元组
Python 的元组与列表类似,不同之处在于元组的元素不能修改. 元组使用小括号,列表使用方括号. 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可. 实例1(Python3.0+): tu ...
- 4-2:实现cp命令
#include <stdio.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h& ...
- java线程一之创建线程、线程池以及多线程运行时间统计
线程和进程的基本概念 进程和线程是动态的概念. 进程是 "执行中的程序",是一个动词,而程序是一个名词,进程运行中程序的"代码",而且还有自己的 ...
- Android - 时间 日期相关组件
源码下载地址 : -- CSDN : http://download.csdn.net/detail/han1202012/6856737 -- GitHub : https://github.co ...