[BZOJ3779]重组病毒(LCT+DFS序线段树)
同[BZOJ4817]树点涂色,只是多了换根操作,分类讨论下即可。
#include<cstdio>
#include<algorithm>
#define lc ch[x][0]
#define rc ch[x][1]
#define ls (x<<1)
#define rs (ls|1)
#define lson ls,L,mid
#define rson rs,mid+1,R
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
#define For(i,x) for (int i=h[x],k; i; i=nxt[i])
typedef long long ll;
using namespace std; const int N=;
char op[];
ll tag[N<<],sm[N<<];
int n,m,u,v,x,rt,cnt,tim,rev[N],h[N],nxt[N<<],to[N<<];
int L[N],R[N],dep[N],fa[N][],ch[N][],sz[N],f[N];
void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; } inline int rd(){
int x=; char ch=getchar(); bool f=;
while (ch<'' || ch>'') f|=ch=='-',ch=getchar();
while (ch>='' && ch<='') x=(x<<)+(x<<)+(ch^),ch=getchar();
return f ? -x : x;
} int jump(int x,int k){
for (int i=; ~i; i--) if (k&(<<i)) x=fa[x][i]; return x;
} void push(int x,int L,int R){
if (!tag[x]) return;
int mid=(L+R)>>;
sm[ls]+=tag[x]*(mid-L+); tag[ls]+=tag[x];
sm[rs]+=tag[x]*(R-mid); tag[rs]+=tag[x];
tag[x]=;
} void mdf(int x,int L,int R,int l,int r,int k){
if (L==l && r==R){ sm[x]+=1ll*k*(R-L+); tag[x]+=k; return; }
int mid=(L+R)>>; push(x,L,R);
if (r<=mid) mdf(lson,l,r,k);
else if (l>mid) mdf(rson,l,r,k);
else mdf(lson,l,mid,k),mdf(rson,mid+,r,k);
sm[x]=sm[ls]+sm[rs];
} ll que(int x,int L,int R,int l,int r){
if (L==l && r==R) return sm[x];
int mid=(L+R)>>; push(x,L,R);
if (r<=mid) return que(lson,l,r);
else if (l>mid) return que(rson,l,r);
else return que(lson,l,mid)+que(rson,mid+,r);
} void dfs(int x){
L[x]=++tim; dep[x]=dep[fa[x][]]+; sz[x]=;
rep(i,,) fa[x][i]=fa[fa[x][i-]][i-];
mdf(,,n,L[x],L[x],dep[x]);
For(i,x) if ((k=to[i])!=fa[x][]) fa[k][]=x,f[k]=x,dfs(k),sz[x]+=sz[k];
R[x]=tim;
} bool isrt(int x){ return (!f[x]) || (ch[f[x]][]!=x && ch[f[x]][]!=x); }
void put(int x){ swap(lc,rc); rev[x]^=; }
void push(int x){ if (rev[x]) put(lc),put(rc),rev[x]=; }
void pd(int x){ if (!isrt(x)) pd(f[x]); push(x); } void rot(int x){
int y=f[x],z=f[y],w=ch[y][]==x;
if (!isrt(y)) ch[z][ch[z][]==y]=x;
f[x]=z; f[y]=x; f[ch[x][w^]]=y;
ch[y][w]=ch[x][w^]; ch[x][w^]=y;
} void splay(int x){
pd(x);
while (!isrt(x)){
int y=f[x],z=f[y];
if (!isrt(y)) (ch[z][]==y)^(ch[y][]==x) ? rot(x) : rot(y);
rot(x);
}
} void work(int x,int k){
if (rt==x) mdf(,,n,,n,k);
else if (L[rt]>=L[x] && L[rt]<=R[x]){
int t=jump(rt,dep[rt]-dep[x]-);
if (L[t]>) mdf(,,n,,L[t]-,k);
if (R[t]<n) mdf(,,n,R[t]+,n,k);
}else mdf(,,n,L[x],R[x],k);
} int find(int x){
push(x);
while (lc) x=lc,push(x);
return x;
} void access(int x){
for (int y=; x; y=x,x=f[x]){
splay(x);
if (rc) work(find(rc),);
if (y) work(find(y),-);
rc=y;
}
} void mkrt(int x){ access(x); splay(x); put(x); } int main(){
freopen("bzoj3779.in","r",stdin);
freopen("bzoj3779.out","w",stdout);
n=rd(); m=rd();
rep(i,,n) u=rd(),v=rd(),add(u,v),add(v,u);
dfs(); rt=;
while (m--){
scanf("%s",op); x=rd();
if (op[]=='L') access(x);
if (op[]=='C') mkrt(x),rt=x;
if (op[]=='Q'){
if (rt==x) printf("%.10lf\n",.*que(,,n,,n)/n);
else if (L[rt]>=L[x] && L[rt]<=R[x]){
int t=jump(rt,dep[rt]-dep[x]-);
ll res1=L[t]> ? que(,,n,,L[t]-) : ;
ll res2=R[t]<n ? que(,,n,R[t]+,n) : ;
printf("%.10lf\n",.*(res1+res2)/(n-sz[t]));
}else printf("%.10lf\n",.*que(,,n,L[x],R[x])/sz[x]);
}
}
return ;
}
[BZOJ3779]重组病毒(LCT+DFS序线段树)的更多相关文章
- 【BZOJ3779】重组病毒 LCT+DFS序
[BZOJ3779]重组病毒 Description 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力极强.为了阻止这种病毒传播,某安全机构策 ...
- bzoj4817/luogu3703 树点涂色 (LCT+dfs序+线段树)
我们发现,这个染色的操作他就很像LCT中access的操作(为什么??),然后就自然而然地想到,其实一个某条路径上的颜色数量,就是我们做一个只有access操作的LCT,这条路径经过的splay的数量 ...
- BZOJ.4817.[SDOI2017]树点涂色(LCT DFS序 线段树)
题目链接 操作\(1.2\)裸树剖,但是操作\(3\)每个点的答案\(val\)很不好维护.. 如果我们把同种颜色的点划分到同一连通块中,那么向根染色的过程就是Access()! 最初所有点间都是虚边 ...
- [BZOJ4817][SDOI2017]树点涂色(LCT+DFS序线段树)
4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 692 Solved: 408[Submit][Status ...
- [BZOJ3779]重组病毒:Link-Cut Tree+线段树
分析 其实其他的题解说的都很清楚了. 一个点出发感染到根结点所花费的时间是路径上虚边的条数+1. RELEASE相当于\(access()\). RECENTER相当于\(makeroot()\).( ...
- Educational Codeforces Round 6 E dfs序+线段树
题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...
- 【BZOJ-3252】攻略 DFS序 + 线段树 + 贪心
3252: 攻略 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 339 Solved: 130[Submit][Status][Discuss] D ...
- Codeforces 343D Water Tree(DFS序 + 线段树)
题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...
- BZOJ2434 [Noi2011]阿狸的打字机(AC自动机 + fail树 + DFS序 + 线段树)
题目这么说的: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...
随机推荐
- 简单对象List自定义属性排序
<body> <div> sort()对数组排序,不开辟新的内存,对原有数组元素进行调换 </div> <div id="showBox" ...
- 利用反射型XSS二次注入绕过CSP form-action限制
利用反射型XSS二次注入绕过CSP form-action限制 翻译:SecurityToolkit 0x01 简单介绍 CSP(Content-Security-Policy)是为了缓解XSS而存在 ...
- 【算法学习】【洛谷】cdq分治 & P3810 三维偏序
cdq是何许人也?请参看这篇:https://wenku.baidu.com/view/3b913556fd0a79563d1e7245.html. 在这篇论文中,cdq提出了对修改/询问型问题(Mo ...
- Wannacry样本取证特征与清除
一.取证特征 1)网络域名特征 http://www.iuqerfsodp9ifjaposdfjhgosurijfaewrwergwea.com 2)文件特征 母体文件 mssecsvc.exe c: ...
- MySQL 5.6 GTID Replication【转】
一. MySQL 5.6引入了GTID的概念,那么GTID是何方神圣?其实也不复杂,就是一个全局事务标示符.使用GTID时,每次事务提交都会在binlog里生成1个唯一的标示符,它由UUID和事务ID ...
- python小工具之读取host文件
# -*- coding: utf-8 -*- # @Time : 2018/9/12 21:09 # @Author : cxa # @File : readhostfile.py # @Softw ...
- 如何开启mysql5.5的客户端服务 命令行打开方法
MySQL分为两个部分,服务器端和客户端,只有服务器端的服务开启后,才可以通过客户端登录到MySQL数据库.这里介绍如何用命令行方式开启mysql的客户端服务. 在计算机上安装好mysql软件 我 ...
- 07 go语言
Home Alexey Palazhchenko edited this page on 9 Jul · 89 revisions Welcome to the Go wiki, a collec ...
- cbow&&skipgram详细
前面:关于层次huffman树和负例采样也要知道的,这里就不详细写了 来源于:https://mp.weixin.qq.com/s?__biz=MzI4MDYzNzg4Mw==&mid=224 ...
- java基础28 单例集合Collection下的List和Set集合
单例集合体系: ---------| collection 单例集合的根接口--------------| List 如果实现了list接口的集合类,具备的特点:有序,可重复 注:集合 ...