bzoj3779: 重组病毒 link-cut-tree
这道题看了做了个神转换.....推荐个博客给各位大爷看看吧神犇传送门
代码敲了半天....题目也读了半天 线段树维护的东西很容易和lct混在一起 调了调能过也是很开心啊 运气比较好吧233
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int M=<<;
int read(){
int ans=,f=,c=getchar();
while(c<''||c>''){if(c=='-') f=-; c=getchar();}
while(c>=''&&c<=''){ans=ans*+(c-''); c=getchar();}
return ans*f;
}
int n,m,rt;
int next[M],sum,father[M],deep[M],first[M],second[M];
struct Edge{int u,v,from;}e[*M];
void ins(int a,int b){sum++; e[sum].u=a; e[sum].v=b; e[sum].from=next[a]; next[a]=sum;}
void insert(int a,int b){ins(a,b); ins(b,a);}
struct node{int l,r; LL sum,tag;}tr[M*];
int c[M][],fa[M],dfsum,rev[M];
void build(int x,int l,int r){
tr[x].l=l; tr[x].r=r;
if(l==r) return ;
int mid=(l+r)>>;
build(x<<,l,mid); build(x<<^,mid+,r);
}
void cal(int x,int w){tr[x].sum+=1LL*(tr[x].r-tr[x].l+)*w;}
void push_up(int x){tr[x].sum=tr[x<<].sum+tr[x<<^].sum;}
void push_down(int x){
if(!tr[x].tag) return ;
int w=tr[x].tag; tr[x].tag=;
int l=x<<,r=x<<^;
tr[l].tag+=w; cal(l,w);
tr[r].tag+=w; cal(r,w);
}
void push_add(int x,int L,int R,int w){
if(L>R) return ;
if(L<=tr[x].l&&tr[x].r<=R){
cal(x,w);
tr[x].tag+=1LL*w; return ;
}
if(tr[x].l==tr[x].r) return ;
push_down(x);
int mid=(tr[x].l+tr[x].r)>>;
if(L<=mid) push_add(x<<,L,R,w);
if(R>mid) push_add(x<<^,L,R,w);
push_up(x);
}
LL push_ans(int x,int L,int R){
if(L>R) return ;
if(L<=tr[x].l&&tr[x].r<=R) return tr[x].sum;
//if(tr[x].l==tr[x].r) return 0;
LL ans=; push_down(x);
int mid=(tr[x].l+tr[x].r)>>;
if(L<=mid) ans+=push_ans(x<<,L,R);
if(R>mid) ans+=push_ans(x<<^,L,R);
return ans;
}
void dfs(int x,int old){
father[x]=fa[x]=old;
first[x]=++dfsum;
deep[x]=deep[old]+;
push_add(,first[x],first[x],deep[x]);
for(int i=next[x];i;i=e[i].from) if(e[i].v!=old) dfs(e[i].v,x);
second[x]=dfsum;
}
bool isrt(int x){return !x||(c[fa[x]][]!=x&&c[fa[x]][]!=x);}//0也算
void down(int x){
if(!rev[x]) return ;
rev[x]=;
int l=c[x][],r=c[x][];
if(l) swap(c[l][],c[l][]),rev[l]^=;
if(r) swap(c[r][],c[r][]),rev[r]^=;
}
void rotate(int x){
int y=fa[x],z=fa[y],l=,r=;
if(c[y][]==x) l=,r=;
if(!isrt(y)) c[z][c[z][]==y]=x;
fa[y]=x; fa[x]=z; fa[c[x][r]]=y;
c[y][l]=c[x][r]; c[x][r]=y;
}
int st[M],top;
void splay(int x){
st[++top]=x; for(int i=x;!isrt(i);i=fa[i]) st[++top]=fa[i];
while(top) down(st[top--]);
while(!isrt(x)){
int y=fa[x],z=fa[y];
if(!isrt(y)){
if(c[z][]==y^c[y][]==x) rotate(x);
else rotate(y);
}
rotate(x);
}
}
bool inson(int x,int y){return first[x]<=first[y]&&second[y]<=second[x];}
int wson(int x,int y){
for(int i=next[x];i;i=e[i].from) if(e[i].v!=father[x])
if(first[e[i].v]<=first[y]&&second[y]<=second[e[i].v]) return e[i].v;
return ;
}
void add(int x,int w){
if(x==rt) push_add(,,n,w);
else if(inson(x,rt)){
int p=wson(x,rt);
push_add(,,first[p]-,w);
push_add(,second[p]+,n,w);
}
else push_add(,first[x],second[x],w);
}
int find(int x){
while(c[x][]) down(x),x=c[x][];
return x;
}
void acs(int x){
int y=;
while(x){
splay(x);
if(c[x][]) add(find(c[x][]),);
if(y) add(find(y),-);
c[x][]=y; y=x; x=fa[x];
}
}
double addup(int x){
if(x==rt) return (double)push_ans(,,n)/n;
if(inson(x,rt)){
int p=wson(x,rt);
return ((double)push_ans(,,first[p]-)+(double)push_ans(,second[p]+,n))/(n-(second[p]-first[p]+));
}
else return (double)push_ans(,first[x],second[x])/(second[x]-first[x]+);
}
void mrt(int x){splay(x); rt=x; swap(c[x][],c[x][]); rev[x]^=;}
int main()
{
int x,y;
n=read(); m=read();
for(int i=;i<n;i++) x=read(),y=read(),insert(x,y);
rt=; build(,,n); dfs(,);
char ch[];
for(int i=;i<=m;i++){
scanf("%s",ch); x=read();
if(ch[]=='Q') printf("%.10lf\n",addup(x));
else{
acs(x);
if(ch[]=='C') mrt(x);
}
}
return ;
}
bzoj3779: 重组病毒 link-cut-tree的更多相关文章
- [BZOJ3779]重组病毒:Link-Cut Tree+线段树
分析 其实其他的题解说的都很清楚了. 一个点出发感染到根结点所花费的时间是路径上虚边的条数+1. RELEASE相当于\(access()\). RECENTER相当于\(makeroot()\).( ...
- 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, ...
随机推荐
- Vue-router使用
Vue路由:--------------------------------------------------------1 .Vue-rouer入门2 .子路由3 .路由传参4 .多路由区域操作5 ...
- Kotlin怎样使用Android的Dagger2
作者:Antonio Leiva 时间:Apr 11, 2017 原文链接:https://antonioleiva.com/dagger-android-kotlin/ 在Android上,创建去耦 ...
- ThinkPHP5作业管理系统中处理学生未交作业与已交作业信息
在作业管理系统中,学生登陆到个人中心后可以通过左侧的菜单查看自己已经提交的作业和未提交作业.那么在系统中如何实现这些数据的查询的呢?首先我们需要弄清楚学生(Student).班级(class).作业提 ...
- Week1 Team Homework #1 from Z.XML-对于学长项目《shield star》的思考和看法
试用了一下学长黄杨等人开发的<shield star>游戏. 其实作为一个学弟,我对cocos2d-x引擎还算是比较了解,所以对于这样一款很“典型 ...
- [整理]修改git 默认编辑器为vim
git config --global core.editor vim
- UnrealEngine4入门(一) 新建一个c++项目
epic games宣布ue4免费使用(游戏发布之后,每个季度大于3000美元则收取收益的5%)之后,吸引了大批看好VR和AR前景的游戏开发者.不过国内(中文)ue4教程和资料太少,而且一大部分资料都 ...
- STL 六大部件
stl具有上面6大部件 容器是存储数据的,原理主要是模板,容器只是负责存储数据,并不关心内存的存储情况,所以出现了分配器,分配器主要是负责为容器分配内存的,对于数据的操作被封装为一个个函数,也就是算法 ...
- Linux的常用目录学习笔记
首先,先查看一下Linuxi的一级目录结构: ls: /:表示根目录,文件系统的入口,最高一级目录. bin和sbin:命令保存目录,bin是普通用户能,sbin是root用户用的:/bin存放着系统 ...
- lintcode-92-背包问题
92-背包问题 在n个物品中挑选若干物品装入背包,最多能装多满?假设背包的大小为m,每个物品的大小为A[i] 注意事项 你不可以将物品进行切割. 样例 如果有4个物品[2, 3, 5, 7] 如果背包 ...
- 【SSH】——hql的使用方式及实现原理
[含义] hql,即Hibernate Query Language.它与我们熟知的sql很类似,它最大的特点就是对查询进行了面向对象的封装,下面会在具体例子中说明. sql查询的是数据库中的表或字 ...