[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序线段树)的更多相关文章

  1. 【BZOJ3779】重组病毒 LCT+DFS序

    [BZOJ3779]重组病毒 Description 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力极强.为了阻止这种病毒传播,某安全机构策 ...

  2. bzoj4817/luogu3703 树点涂色 (LCT+dfs序+线段树)

    我们发现,这个染色的操作他就很像LCT中access的操作(为什么??),然后就自然而然地想到,其实一个某条路径上的颜色数量,就是我们做一个只有access操作的LCT,这条路径经过的splay的数量 ...

  3. BZOJ.4817.[SDOI2017]树点涂色(LCT DFS序 线段树)

    题目链接 操作\(1.2\)裸树剖,但是操作\(3\)每个点的答案\(val\)很不好维护.. 如果我们把同种颜色的点划分到同一连通块中,那么向根染色的过程就是Access()! 最初所有点间都是虚边 ...

  4. [BZOJ4817][SDOI2017]树点涂色(LCT+DFS序线段树)

    4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 692  Solved: 408[Submit][Status ...

  5. [BZOJ3779]重组病毒:Link-Cut Tree+线段树

    分析 其实其他的题解说的都很清楚了. 一个点出发感染到根结点所花费的时间是路径上虚边的条数+1. RELEASE相当于\(access()\). RECENTER相当于\(makeroot()\).( ...

  6. Educational Codeforces Round 6 E dfs序+线段树

    题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...

  7. 【BZOJ-3252】攻略 DFS序 + 线段树 + 贪心

    3252: 攻略 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 339  Solved: 130[Submit][Status][Discuss] D ...

  8. Codeforces 343D Water Tree(DFS序 + 线段树)

    题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...

  9. BZOJ2434 [Noi2011]阿狸的打字机(AC自动机 + fail树 + DFS序 + 线段树)

    题目这么说的: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...

随机推荐

  1. 在Linode VPS上搭建最新版Transmission

    在Linode VPS上搭建最新版Transmission 2015-09-16 by Hansen 原文链接:http://www.hansendong.me/archives/124.html 以 ...

  2. RTSP消息交互过程

    c表示客户端,s表示RTSP服务器端 第一步:查询服务器可用方法 1 c---s :OPTION request //查询s有哪些方法可用 s---c:OPTION response //s回应信息的 ...

  3. ActiveMQ实现消息的发送与接受

    activemq是apache的一个JMS接口的实现产品,java中定义了JMS规范,虽然RocketMQ,kafka现在比较火,但是还是建议先学一下activeMQ再学其他两个就容易很多 首先可以下 ...

  4. socket相关系统调用的调用流程

    最近一直在读内核网络协议栈源码,这里以ipv4/tcp为例对socket相关系统调用的流程做一个简要整理,这些相关系统调用的内部细节虽然各有不同,但其调用流程则基本一致: 调用流程: (1)系统调用 ...

  5. csv导入mysql提示错误[Error Code] 1290 - The MySQL server is running with the --secure-file-priv option 解决方法【转】

    解决方法: 1.进入mysql查看secure_file_prive的值 mysql>SHOW VARIABLES LIKE "secure_file_priv"; secu ...

  6. maven bat脚本打包

    脚本内容: @echo off echo 正在设置临时环境变量 set JAVA_HOME=C:\Program Files\Java\jdk1.6.0_45 set MAVEN_HOME=D:\ap ...

  7. Spring入门实例

    Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架. 控制反转:应 ...

  8. html-介绍

    一:概述 HTML是英文Hyper Text Mark-up Language(超文本标记语言)的缩写,他是一种制作万维网页面标准语言(标记).相当于定义统一的一套规则,大家都来遵守他,这样就可以让浏 ...

  9. python基础-类的继承

    继承:承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”.“父类. 继承的过程,就是从一般到特殊的过程.要实现继承,可以通过“继承”(Inheritance)和“组合”(Compositio ...

  10. No.1 selenium学习之路之浏览器操作

    selenium基础,首先就是浏览器的相关操作 下面描述几种浏览器的常用操作 1.打开浏览器 webdriver后面添加想要打开的浏览器 Ie或者Chrome 2.打开指定页面(百度) 3.休眠时间 ...