【以前的空间】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\),动态树的一种,又可以 ...
随机推荐
- Java应用基础微专业-设计篇
第1章--抽象与接口 1.1 抽象 An abstract class can be created without abstract methods, the purpose of doing th ...
- JAVA基础学习之路(五)数组的定义及使用
什么是数组:就是一堆相同类型的数据放一堆(一组相关变量的集合) 定义语法: 1.声明并开辟数组 数据类型 数组名[] = new 数据类型[长度]: 2.分布完成 声明数组:数据类型 数组名 [] = ...
- 文件上传:CommonsMultipartResolver
一. 简介 CommonsMultipartResolver是基于Apache的Commons FileUpload来实现文件上传功能的,主要作用是配置文件上传的一些属性. 二. 配置 1)依赖Apa ...
- 并发HashMap的put操作引起死循环
今天研读Java并发容器和框架时,看到为什么要使用ConcurrentHashMap时,其中有一个原因是:线程不安全的HashMap, HashMap在并发执行put操作时会引起死循环,是因为多线程会 ...
- python常用命令—终端安装win32的两种方法
1, pip install pywin32 2, pip install pypiwin32
- 动画效果 ObjectAnimator
学习了一下动画效果的使用,做一下笔记 ImageView imageView = findViewById(R.id.imageView); ObjectAnimator.ofFloat(imageV ...
- sql STUFF 分组
---将sql想关的数据放到一个字段里 select r.Region_Name, )) [text()] from City c2 inner join Region as r2 on c2.Reg ...
- SpringCloud IDEA 教学 (一) Eureka的简介与服务注册中心的建立
写在开头 SpringCloud进来成为业界排名靠前的微服务框架,最核心功能就是搭建微服务,并在此基础上衍生出一系列功能,如断路器(Hystrix).断路监控.管理配置.Zuul.OAuth2等功能. ...
- node.js应用--转载
最近,在向大学生们介绍 HTML5 的时候,我想要对他们进行问卷调查,并向他们显示实时更新的投票结果.鉴于此目的,我决定快速构建一个用于此目的的问卷调查应用程序.我想要一个简单的架构,不需要太多不同的 ...
- java.net.ProtocolException: Server redirected too many times
网页爬虫时,原来正常的代码,可能是因为网站做了cookie校验处理,报异常:java.net.ProtocolException: Server redirected too many times 表 ...