Solution -「BZOJ 3779」重组病毒
Description
Link.
Given is a tree. Every node initially has a color which is different from others'. (called \(col_{x}\))
Def: \(\text{dis}(x,y)\): the number of different colors on the simple path between x and y.
Supporting the following operations:
RELEASE x
: For each \(y\) on \(\text{path}(x,rt)\), make \(col_{y}\)=a new color which doesn't exist before.RECENTER x
: Make \(x\) become the new root after runningRELEASE x
.REQUEST x
: Print: for each \(y\) in \(\text{subtree}(x)\), the sum of \(\text{dis}(y,rt)\) divided the number of nodes in \(\text{subtree}(x)\).
Solution
Link Cut Tree.
We can know that \(\text{dis}(x,rt)\) is the number of Fake Edges on \(\text{path}(x,rt)\) pluses one.
If we change a Real Edge \((u,v)\), where \(dep_{u}<dep_{v}\) into a Fake Edge, for each node \(x\) in \(\text{subtree}(v)\), \(\text{dis}(x,rt)\) will be decreased by \(1\).
Vice versa.
In order to support such operation: decrease the subtree by \(1\), we can fix the DFS order of the given tree.
However, we also need to change the root. How can we fix the DFS order of the given tree?
Let's have a discussion. Denote \(x\) for the current operating node, \(rt\) for the current root.
- if \(rt=x\): modify the whole tree directly.
- if \(rt\) isn't in \(\text{subtree}(x)\): modify \(\text{subtree}(x)\).
- if \(rt\) is in \(\text{subtree}(x)\): modify \(\text{subtree}(x)\) and cancel the modfication of \(\text{subtree}(rt)\)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
vector<int> e[100010];
int n,m,indfn[100010],outdfn[100010],sjc,fa[100010][20],dep[100010],rtnow=1;
#define check(x,f) ((indfn[x]<indfn[f])|(indfn[x]>outdfn[f])) // check whether x isn't in subtree(f)
void dfs(int x,int las)
{
dep[x]=dep[las]+1,fa[x][0]=las,indfn[x]=++sjc;
for(int i=1;i^20;++i) fa[x][i]=fa[fa[x][i-1]][i-1];
for(unsigned int i=0;i<e[x].size();++i) if(e[x][i]^las) dfs(e[x][i],x);
outdfn[x]=sjc;
}
int getkth(int x,int k)
{
if(k==0) return x;
else
{
for(int i=0;i^20;++i) if((k>>i)&1) x=fa[x][i];
return x;
}
}
struct LinearTree
{
struct node
{
LL val,tag;
}nodes[400010];
void turn(int x,int l,int r)
{
if(nodes[x].tag)
{
int mid=(l+r)>>1;
nodes[x<<1].val+=(mid-l+1)*nodes[x].tag;
nodes[x<<1|1].val+=(r-mid)*nodes[x].tag;
nodes[x<<1].tag+=nodes[x].tag;
nodes[x<<1|1].tag+=nodes[x].tag;
nodes[x].tag=0;
}
}
void ins(int l,int r,int x,int fr,int ba,int val)
{
if(fr>ba||l>ba||r<fr) return;
if(l>=fr&&r<=ba) nodes[x].val+=(r-l+1)*val,nodes[x].tag+=val;
else
{
int mid=(l+r)>>1;
turn(x,l,r);
ins(l,mid,x<<1,fr,ba,val);
ins(mid+1,r,x<<1|1,fr,ba,val);
nodes[x].val=nodes[x<<1].val+nodes[x<<1|1].val;
}
}
LL find(int l,int r,int x,int fr,int ba)
{
if(fr>ba||l>ba||r<fr) return 0;
if(l>=fr&&r<=ba) return nodes[x].val;
else
{
int mid=(l+r)>>1;
turn(x,l,r);
return find(l,mid,x<<1,fr,ba)+find(mid+1,r,x<<1|1,fr,ba);
}
}
void modify(int x,LL val)
{
if(rtnow==x) ins(1,n,1,1,n,val);
else if(check(rtnow,x)) ins(1,n,1,indfn[x],outdfn[x],val);
else
{
int tmp=getkth(rtnow,dep[rtnow]-dep[x]-1);
ins(1,n,1,1,indfn[tmp]-1,val);
ins(1,n,1,outdfn[tmp]+1,n,val);
}
}
}lrt;
struct LinkCutTree
{
#define wis(x) (nodes[nodes[x].fa].ch[1]==(x))
#define isrt(x) ((nodes[nodes[x].fa].ch[0]^(x))&&(nodes[nodes[x].fa].ch[1]^(x)))
struct node
{
int ch[2],fa;
bool rev;
}nodes[100010];
void turn_down(int x)
{
if(nodes[x].rev)
{
swap(nodes[x].ch[0],nodes[x].ch[1]);
if(nodes[x].ch[0]) nodes[nodes[x].ch[0]].rev^=1;
if(nodes[x].ch[1]) nodes[nodes[x].ch[1]].rev^=1;
nodes[x].rev=0;
}
}
void turn_whole(int x)
{
if(!isrt(x)) turn_whole(nodes[x].fa);
turn_down(x);
}
void rotate(int x)
{
int f=nodes[x].fa,ff=nodes[f].fa,t=wis(x);
nodes[x].fa=ff;
if(!isrt(f)) nodes[ff].ch[wis(f)]=x;
nodes[f].ch[t]=nodes[x].ch[t^1];
nodes[nodes[x].ch[t^1]].fa=f;
nodes[x].ch[t^1]=f;
nodes[f].fa=x;
}
void splay(int x)
{
turn_whole(x);
while(!isrt(x))
{
int f=nodes[x].fa;
if(!isrt(f)) rotate((wis(x)^wis(f))?x:f);
rotate(x);
}
}
int findleft(int x)
{
turn_down(x);
while(nodes[x].ch[0]) x=nodes[x].ch[0],turn_down(x);
return x;
}
void access(int x)
{
for(int y=0;x;y=x,x=nodes[x].fa)
{
splay(x);
if(nodes[x].ch[1]) lrt.modify(findleft(nodes[x].ch[1]),1);
if(y) lrt.modify(findleft(y),-1);
nodes[x].ch[1]=y;
}
}
void makert(int x){access(x),splay(x),nodes[x].rev^=1;}
}lct;
char opt[20];
int opx;
template<typename T>
void read(T &hhh)
{
T x=0,f=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^'0'),c=getchar();
if(~f) hhh=x;
else hhh=-x;
}
int main()
{
read(n),read(m);
for(int i=1,x,y;i<n;++i)
{
read(x),read(y);
e[x].emplace_back(y);
e[y].emplace_back(x);
}
dfs(1,0);
for(int i=1;i<=n;++i) lrt.ins(1,n,1,indfn[i],indfn[i],dep[i]),lct.nodes[i].fa=fa[i][0];
while(m--)
{
scanf("%s",opt),read(opx);
if(strcmp(opt,"RELEASE")==0) lct.access(opx);
else if(strcmp(opt,"RECENTER")==0) lct.makert(opx),rtnow=opx;
else
{
if(rtnow==opx) printf("%.10f\n",double(lrt.find(1,n,1,1,n))/n);
else if(check(rtnow,opx)) printf("%.10f\n",double(lrt.find(1,n,1,indfn[opx],outdfn[opx]))/(outdfn[opx]-indfn[opx]+1));
else
{
int tmp=getkth(rtnow,dep[rtnow]-dep[opx]-1);
printf("%.10f\n",double(lrt.find(1,n,1,1,indfn[tmp]-1)+lrt.find(1,n,1,outdfn[tmp]+1,n))/(indfn[tmp]+n-outdfn[tmp]-1));
}
}
}
return 0;
}
Solution -「BZOJ 3779」重组病毒的更多相关文章
- 【bzoj 3779】重组病毒
Description 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力极强.为了阻止这种病毒传播,某安全机构策划了一次实验,来研究这种病毒. ...
- Solution -「BZOJ 3812」主旋律
\(\mathcal{Description}\) Link. 给定含 \(n\) 个点 \(m\) 条边的简单有向图 \(G=(V,E)\),求 \(H=(V,E'\subseteq E)\ ...
- Solution -「BZOJ #3786」星系探索
\(\mathcal{Description}\) Link. 给定一棵含 \(n\) 个点的有根树,点有点权,支持 \(q\) 次操作: 询问 \(u\) 到根的点权和: 修改 \(u\) ...
- Solution -「BZOJ 4316」小C的独立集
\(\mathcal{Description}\) Link. 求包含 \(n\) 个结点 \(m\) 条边的仙人掌的最大独立集. \(n\le5\times10^4\),\(m\le6\ ...
- Solution -「BZOJ 3331」压力
\(\mathcal{Description}\) Link. 给定一个 \(n\) 个点 \(m\) 条边的连通无向图,并给出 \(q\) 个点对 \((u,v)\),令 \(u\) 到 \ ...
- 「BZOJ 4228」Tibbar的后花园
「BZOJ 4228」Tibbar的后花园 Please contact lydsy2012@163.com! 警告 解题思路 可以证明最终的图中所有点的度数都 \(< 3\) ,且不存在环长是 ...
- 「BZOJ 3645」小朋友与二叉树
「BZOJ 3645」小朋友与二叉树 解题思路 令 \(G(x)\) 为关于可选大小集合的生成函数,即 \[ G(x)=\sum[i\in c ] x^i \] 令 \(F(x)\) 第 \(n\) ...
- 「BZOJ 4502」串
「BZOJ 4502」串 题目描述 兔子们在玩字符串的游戏.首先,它们拿出了一个字符串集合 \(S\),然后它们定义一个字符串为"好"的,当且仅当它可以被分成非空的两段,其中每一段 ...
- 「BZOJ 4289」 PA2012 Tax
「BZOJ 4289」 PA2012 Tax 题目描述 给出一个 \(N\) 个点 \(M\) 条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点 \(1\) 到点 \( ...
- 「BZOJ 2534」 L - gap字符串
「BZOJ 2534」 L - gap字符串 题目描述 有一种形如 \(uv u\) 形式的字符串,其中 \(u\) 是非空字符串,且 \(v\) 的长度正好为 \(L\), 那么称这个字符串为 \( ...
随机推荐
- 【python基础】函数-初识函数
函数是带名字的代码块,用于完成具体的工作,无需反复编写完成该工作的代码.之前我们接触过print函数,数据类型转换中的int函数.str函数,还有列表中的append函数.pop函数.remove函数 ...
- @Target元注解的使用
@Target注解标记另外的注解用于限制此注解可以应用哪种Java元素类型.先看Java SE 8中@Target是如何声明的: package java.lang.annotation; publi ...
- Java 设计模式实战系列—策略模式
从优惠打折活动说起 电商平台为了增加销量经常搞一些活动,比如 618.双十一,还有一些节假日活动,根据销量的变化又经常更新不同的活动.最开始为了增加销量,全场都六折: // 打六折 public Bi ...
- python中引用自己封装的包飘红线处理办法
1.安装 opencv-contrib-python 可解决引用自己包名提示 无法识别 2.取消unresolved referencesde 的勾勾
- ZIM|一站式接入,打通 RTC 和 IM 组合拳
从用户信息.用户心跳到用户间私人与聊天室通信,IM 一直是互联网世界中不可或缺的基础建设之一.早在连麦和直播诞生之前,IM 就已是在通讯领域内服役多年的老兵,而随着线上音视频的兴起,IM 不仅没有没落 ...
- 前端uni-app自定义精美全端复制文本插件,支持全端文本复制插件 可设置复制按钮颜色
随着技术的发展,开发的复杂度也越来越高,传统开发方式将一个系统做成了整块应用,经常出现的情况就是一个小小的改动或者一个小功能的增加可能会引起整体逻辑的修改,造成牵一发而动全身. 通过组件化开发,可以有 ...
- [Spring+SpringMVC+Mybatis]框架学习笔记(四):Spring实现AOP
上一章:[Spring+SpringMVC+Mybatis]框架学习笔记(三):Spring实现JDBC 下一章:[Spring+SpringMVC+Mybatis]框架学习笔记(五):SpringA ...
- 2022级HAUT新生周赛题解汇总
2022级HAUT新生周赛(零)题解@:前六题题解 G题比赛模拟题目题解 2022级HAUT新生周赛(一)题解@卞子骏:题解 2022级HAUT新生周赛(二)题解@武其轩:题解 题解2 2022级 ...
- 2023-07-31:用r、e、d三种字符,拼出一个回文子串数量等于x的字符串。 1 <= x <= 10^5。 来自百度。
2023-07-31:用r.e.d三种字符,拼出一个回文子串数量等于x的字符串. 1 <= x <= 10^5. 来自百度. 答案2023-07-31: 大体步骤如下: 1.初始化一个字符 ...
- tcp3次握手
tcp3次握手 1,三次握手流程图 2,三握手过程 当pc1想和pc2建立起连接时 pc1将连接信息写入报文 2.1,报文的序号(seq=x) 同步位(请求建立连接关系: SYN=1 ACK=0 控制 ...