LOJ #6022. 重组病毒
Description
支持以下操作
1.access一个点
2.问一个点上面的重链的个数
3.换根 , 并access原来的根
Solution
对于重链个数 , 我们在 \(access\) 的时候对一个点的子树进行修改 .
换根的话 , 直接 $ mroot $就好了 , 注意要先 \(mroot\) 再 \(rt=x\) , 因为要删去现在的根和 \(x\) 在原来的根下的 \(lca\) 以上那一段的贡献 .
然后查询就讨论一下根在子树内和子树外就行了 .
注意讨论修改和询问的 \(x=rt\) 的情况 .
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int head[N],nxt[N*2],to[N*2],num=0,n,m,L[N],R[N],DFN=0,ch[N][2],fa[N];
bool rev[N];ll t1[N],t2[N];int f[N][19],dep[N],rt=1;
inline void add(int x,int t){
for(int i=x;i<=n;i+=(i&(-i)))t1[i]+=t,t2[i]+=x*t;
}
inline double qry(int x){
ll s1=0,s2=0;
for(int i=x;i;i-=(i&(-i)))s1+=t1[i],s2+=t2[i];
return (double)(s1*(x+1)-s2);
}
inline void link(int x,int y){nxt[++num]=head[x];to[num]=y;head[x]=num;}
inline void dfs(int x,int la){
L[x]=++DFN;
for(int i=1;i<=18;i++)f[x][i]=f[f[x][i-1]][i-1];
for(int i=head[x],u;i;i=nxt[i]){
if((u=to[i])==la)continue;
fa[u]=f[u][0]=x;dep[u]=dep[x]+1;dfs(u,x);
}
add(L[x],1);add((R[x]=DFN)+1,-1);
}
inline bool isrt(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
inline void rotate(int x){
int y=fa[x];bool t=ch[y][1]==x;
ch[y][t]=ch[x][!t];fa[ch[y][t]]=y;ch[x][!t]=y;fa[x]=fa[y];
if(!isrt(y))ch[fa[y]][ch[fa[y]][1]==y]=x;
fa[y]=x;
}
inline void Rev(int x){if(x)rev[x]^=1,swap(ch[x][0],ch[x][1]);}
inline void pushdown(int x){if(rev[x])Rev(ch[x][0]),Rev(ch[x][1]),rev[x]=0;}
inline void Push(int x){if(!isrt(x))Push(fa[x]);pushdown(x);}
inline void splay(int x){
Push(x);
while(!isrt(x)){
int y=fa[x],p=fa[y];
if(isrt(y))rotate(x);
else if((ch[p][0]==y)==(ch[y][0]==x))rotate(y),rotate(x);
else rotate(x),rotate(x);
}
}
inline int lca(int x,int y){
for(int i=18;i>=0;i--)if(dep[f[x][i]]>dep[y])x=f[x][i];
return x;
}
inline void mdf(int x,int t){
if(!x)return ;
pushdown(x);
while(ch[x][0])pushdown(x),x=ch[x][0];
if(x==rt)add(1,t);
if(L[rt]<=L[x] || L[rt]>R[x])add(L[x],t),add(R[x]+1,-t);
else{
int y=lca(rt,x);
add(1,t);add(L[y],-t);add(R[y]+1,t);
}
}
inline double query(int x){
if(x==rt)return qry(n)/n;
if(L[rt]<=L[x] || L[rt]>R[x])return (qry(R[x])-qry(L[x]-1))/(R[x]-L[x]+1);
else{
int y=lca(rt,x);
return (qry(L[y]-1)+qry(n)-qry(R[y]))/(L[y]-1+n-R[y]);
}
}
inline void access(int x){
int y=0;
while(x)splay(x),mdf(ch[x][1],1),ch[x][1]=y,mdf(y,-1),x=fa[y=x];
}
inline void mroot(int x){access(x);splay(x);Rev(x);}
int main(){
freopen("shamate.in","r",stdin);
freopen("shamate.out","w",stdout);
int x,y;
cin>>n>>m;
for(int i=1;i<n;i++){
scanf("%d%d",&x,&y);
link(x,y);link(y,x);
}
dfs(1,1);
char op[10];
while(m--){
scanf("%s%d",op,&x);
if(op[2]=='Q')printf("%.10lf\n",query(x));
else if(op[2]=='L')access(x);
else mroot(x),rt=x;
}
return 0;
}
LOJ #6022. 重组病毒的更多相关文章
- 【BZOJ-3779】重组病毒 LinkCutTree + 线段树 + DFS序
3779: 重组病毒 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 224 Solved: 95[Submit][Status][Discuss] ...
- BZOJ3779重组病毒LCT
题目描述 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力极强.为了阻止这种病毒传播,某安全机构策划了一次实验,来研究这种病毒.实验在一个封闭 ...
- 【bzoj 3779】重组病毒
Description 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力极强.为了阻止这种病毒传播,某安全机构策划了一次实验,来研究这种病毒. ...
- BZOJ 3779 重组病毒 LCT+线段树(维护DFS序)
原题干(由于是权限题我就直接砸出原题干了,要看题意概述的话在下面): Description 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力 ...
- 【BZOJ3779】重组病毒 LCT+DFS序
[BZOJ3779]重组病毒 Description 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力极强.为了阻止这种病毒传播,某安全机构策 ...
- bzoj 3779: 重组病毒 LCT+线段树+倍增
题目: 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力极强.为了阻止这种病毒传播,某安全机构策划了一次实验,来研究这种病毒. 实验在一个封闭 ...
- BZOJ 3779: 重组病毒(线段树+lct+树剖)
题面 escription 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力极强.为了阻止这种病毒传播,某安全机构策划了一次实验,来研究这种病 ...
- bzoj 3779: 重组病毒【LCT+线段树维护dfs序】
%.8lf会WA!!%.8lf会WA!!%.8lf会WA!!要%.10lf!! 和4817有点像,但是更复杂. 首先对于操作一"在编号为x的计算机中植入病毒的一个新变种,在植入一个新变种时, ...
- bzoj千题计划274:bzoj3779: 重组病毒
http://www.lydsy.com/JudgeOnline/problem.php?id=3779 有一棵树,初始每个节点有不同的颜色 操作1:根节点到x的路径上的点 染上一种没有出现过的颜色 ...
随机推荐
- C# 使用ProcessStartInfo调用exe获取不到重定向数据的解决方案
emmmmm,最近在研究WFDB工具箱,C语言写的,无奈本人C语言功底不够,只想直接拿来用,于是打算通过ProcessStartInfo来调取编译出来的exe程序获取输出. 一开始就打算偷懒,从园子里 ...
- Devexpress treelist 控件属性大全
属性列表 1.OptionsSelection: EnableAppearanceForcusedCell:选中的Cell的Appearance设置是否可用.默认为True: EnableAppear ...
- how to trace the error log
Executed as user: WTC\Ebw.Admin. Transaction (Process ID 95) was deadlocked on lock resources with a ...
- CentOS6.5加域
为减少错误已提前关掉了SELinux,防火墙. yum install nss-pam-ldapd -y 第一步:更改主机名为linux.itxdm.me 第二步:更改setup内左边Winbind ...
- Linux 中排除掉筛选的文件
以下命令以网站目录www为例做介绍,有时候更新网站的时候需要保留比如图片目录,或者其他目录就需要这样的操作 实例一: 删除文件夹内所有文件只保留一个文件命令 [root@linuxzgf www]# ...
- Leetcode 102 二叉树的层次遍历 Python
二叉树的层次遍历 给定一个二叉树,返回其按层次遍历的节点值. (即逐层地,从左到右访问所有节点). 例如: 给定二叉树: [3,9,20,null,null,15,7], 3 / \ 9 20 ...
- c++之选择排序和冒泡排序实现
1.冒泡排序 冒泡排序就是通过对比前一个和后一个数的大小,按照规则进行顺序的调换.每一轮对比之后最大或者最小值都会浮到最上面或者沉到最低下. 如:对这一数组进行冒泡排序:int a[5]{34,12 ...
- 队列的理解和实现(一) ----- 循环队列(java实现)
什么是队列 我们都知道栈是先进后出的一种线性表,与之相反的是,队列是一种先进先出的线性表.它只允许在表的一端进行插入,而在另一端进行删除.举个例子来说,在生活中我们买东西需要进行排队,最先排队的可以最 ...
- ubuntu apt update时W: GPG error http://ppa.launchpad.net lucid Release没有公钥无法验证NO_PUBKEY签名问题解决
在安装更新时,即在运行命令行sudo apt-get update 或者运行更新管理器的时候,出现W: GPG 错误: W: GPG error: http://ppa.launchpad.net/o ...
- php 判断两个时间段是否有交集
一开始,没啥思路,全靠百度,记录一下哈 public function demo(){ //例子 $astart = strtotime("1995-06-16 12:00:00" ...