[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'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...
随机推荐
- window下卸载MySQL
更多内容推荐微信公众号,欢迎关注: 网上找来的,留在这做个备份. 1.控制面板里的增加删除程序内进行删除 2.删除MySQL文件夹下的my.ini文件,如果备份好,可以直接将文件夹全部删除 3.开始- ...
- C# IsAssignableFrom与IsSubClassOf 判断匿名类是否继承父类
public class Dog : Animal { public string name { get; set; } } public class Animal { public string i ...
- 安卓微信、QQ自带浏览器 UXSS 漏洞
安卓微信.QQ自带浏览器 UXSS 漏洞 注:PDF报告原文下载链接 Author: hei@knownsec.com Date: 2016-02-29 一.漏洞描述 在安卓平台上的微信及QQ自带浏览 ...
- 2017-2018-2 20179205《网络攻防技术与实践》Windows攻击实验
Windows攻击实验 实验描述: 使用Metaspoit攻击MS08-067,提交正确得到远程shell过程的截图(不少于五张). MS08-067漏洞介绍 MS08-067漏洞的全称为&quo ...
- 使用RegSetValueEx修改注册表时遇到的问题(转)
原文转自 http://blog.csdn.net/tracyzhongcf/article/details/4076870 1.今天在使用RegSetValueEx时发现一个问题: RegSetVa ...
- Django-自动HTML转义
一.自动HTML转义 从模板生成HTML时,总会有变量包含影响最终HTML的字符风险,例如,考虑这个模板的片段: Hello, {{ name }} 起初,这是一种显示用户名的无害方式,但考虑用户输入 ...
- 08 Packages 包
Packages Standard library Other packages Sub-repositories Community Standard library Name Synopsis ...
- vue总结 08状态管理vuex
状态管理 类 Flux 状态管理的官方实现 由于状态零散地分布在许多组件和组件之间的交互中,大型应用复杂度也经常逐渐增长.为了解决这个问题,Vue 提供 vuex:我们有受到 Elm 启发的状态管 ...
- Linux下实现多播(组播)
单播只能发送给一个接收方,但是当给多个接收者发送时,不仅仅耗费流量,而且耗费时间,总流量=每个接收者的流量*接受者. 广播方式是发送给所有的主机,广播的坏处是会造成信息污染,大量的信息会占用网络带宽. ...
- Token机制,防止web页面重复提交
1.业务要求:页面的数据只能被点击提交一次 2.发生原因: 由于重复点击或者网络重发,或者nginx重发等情况会导致数据被重复提交 3.解决办法: 集群环境:采用token加redis(redis单线 ...