https://loj.ac/problem/2537

参考了本题在网上能找到的为数不多的题解。

以及我眼睛瞎没看到需要离散化,还有不开longlong见祖宗。

————————————————————————————

思考一下不难发现,我们的操作相当于对两个数集进行合并,并且重新更新每个数被取到的期望。

权值线段树可以帮我们实现这个功能(当然是要动态开点了)。

然后就思考线段树的合并操作了,orz可我不会啊。

设我们期望让左儿子的数字u成为其父亲的权值,其父亲选最大值的概率为k,u在右儿子数集中比它小的数被选中的期望设为w。

则概率为pu*((1-w)*(1-k)+w*k)=pu*(1-w-k+2*w*k)。

当然右儿子同理。

当然统计w显然不能暴力统计,我们权值线段树维护当前区间所有数被选中的期望和,从左到右扫所有可能的最大区间,这个区间满足有一个儿子的数集并不包含这个区间内的任意一个数。

这样这个区间的期望和就能被缩成了“一个数的期望”,此时的w也很容易被统计出来(就相当于这个区间以前的所有数的期望和,每次扫完一个区间累加即可O(1)求出),那么这个时候就被转换成了区间修改问题。

#include<cmath>
#include<queue>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=3e5+;
const int p=;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
int qpow(int k,int n){
int res=;
while(n){
if(n&)res=(ll)res*k%p;
k=(ll)k*k%p;n>>=;
}
return res;
}
struct tree{
int l,r;
ll p,lazy;
}tr[N*];
int fa[N],son[N],ch[N][],rt[N],pool,n,m,b[N],q[N];
inline void LSH(){
sort(b+,b+m+);
m=unique(b+,b+m+)-b-;
for(int i=;i<=n;i++)
if(!son[i])
q[i]=lower_bound(b+,b+m+,q[i])-b;
}
void insert(int &x,int l,int r,int k){
tr[x=++pool].p=;tr[x].lazy=;
if(l==r)return;
int mid=(l+r)>>;
if(k<=mid)insert(tr[x].l,l,mid,k);
else insert(tr[x].r,mid+,r,k);
}
inline void push(int x){
if(tr[x].lazy<=)return;
(tr[tr[x].l].lazy*=tr[x].lazy)%=p;
(tr[tr[x].r].lazy*=tr[x].lazy)%=p;
(tr[tr[x].l].p*=tr[x].lazy)%=p;
(tr[tr[x].r].p*=tr[x].lazy)%=p;
tr[x].lazy=;
}
int maxl,maxr;
int merge(int nl,int nr,int l,int r,int k){
if(!nl&&!nr)return ;
if(!nl){
(maxr+=tr[nr].p)%=p;
(tr[nr].p*=((ll)*maxl%p*k%p-k-maxl+)%p+p)%=p;
(tr[nr].lazy*=((ll)*maxl%p*k%p-k-maxl+)%p+p)%=p;
return nr;
}
if(!nr){
(maxl+=tr[nl].p)%=p;
(tr[nl].p*=((ll)*maxr%p*k%p-k-maxr+)%p+p)%=p;
(tr[nl].lazy*=((ll)*maxr%p*k%p-k-maxr+)%p+p)%=p;
return nl;
}
push(nl);push(nr);
int mid=(l+r)>>;
tr[nl].l=merge(tr[nl].l,tr[nr].l,l,mid,k);
tr[nl].r=merge(tr[nl].r,tr[nr].r,mid+,r,k);
tr[nl].p=(tr[tr[nl].l].p+tr[tr[nl].r].p)%p;
return nl;
}
void dfs(int u){
if(!son[u]){
insert(rt[u],,m,q[u]);return;
}
if(son[u]==){
dfs(ch[u][]);
rt[u]=rt[ch[u][]];
}else{
dfs(ch[u][]);dfs(ch[u][]);
maxl=maxr=;
rt[u]=merge(rt[ch[u][]],rt[ch[u][]],,m,q[u]);
}
}
int cnt;
int query(int x,int l,int r){
if(!tr[x].p)return ;
if(l==r){
cnt++;
return (ll)cnt*b[l]%p*tr[x].p%p*tr[x].p%p;
}
push(x);
int mid=(l+r)>>;
return (query(tr[x].l,l,mid)+query(tr[x].r,mid+,r))%p;
}
int main(){
n=read();
for(int i=;i<=n;i++){
fa[i]=read();
ch[fa[i]][son[fa[i]]++]=i;
}
int inv=qpow(,p-);
for(int i=;i<=n;i++){
q[i]=read();
if(son[i])q[i]=(ll)q[i]*inv%p;
else b[++m]=q[i];
}
LSH();
dfs();
printf("%d\n",query(rt[],,m));
return ;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

LOJ2537:[PKUWC2018]Minimax——题解的更多相关文章

  1. LOJ2537 PKUWC2018 Minimax 树形DP、线段树合并

    传送门 题意:自己去看 首先可以知道,每一个点都有几率被选到,所以$i$与$V_i$的关系是确定了的. 所以我们只需要考虑每一个值的取到的概率. 很容易设计出一个$DP$:设$f_{i,j}$为在第$ ...

  2. [LOJ2537] [PKUWC2018] Minimax

    题目链接 LOJ:https://loj.ac/problem/2537 洛谷:https://www.luogu.org/problemnew/show/P5298 Solution 不定期诈尸 好 ...

  3. [PKUWC2018]Minimax 题解

    根据题意,若一个点有子节点,则给出权值:否则可以从子节点转移得来. 若没有子节点,则直接给出权值: 若只有一个子节点,则概率情况与该子节点完全相同: 若有两个子节点,则需要从两个子节点中进行转移. 如 ...

  4. 【题解】PKUWC2018简要题解

    [题解]PKUWC2018简要题解 Minimax 定义结点x的权值为: 1.若x没有子结点,那么它的权值会在输入里给出,保证这类点中每个结点的权值互不相同. 2.若x有子结点,那么它的权值有p的概率 ...

  5. BZOJ5461: [PKUWC2018]Minimax

    BZOJ5461: [PKUWC2018]Minimax https://lydsy.com/JudgeOnline/problem.php?id=5461 分析: 写出\(dp\)式子:$ f[x] ...

  6. 题解-PKUWC2018 Minimax

    Problem loj2537 Solution pkuwc2018最水的一题,要死要活调了一个多小时(1h59min) 我写这题不是因为它有多好,而是为了保持pkuwc2018的队形,与这题类似的有 ...

  7. [PKUWC2018] Minimax

    Description 给定一棵 \(n\) 个节点的树,每个节点最多有两个子节点. 如果 \(x\) 是叶子,则给定 \(x\) 的权值:否则,它的权值有 \(p_x\) 的概率是它子节点中权值的较 ...

  8. BZOJ.5461.[PKUWC2018]Minimax(DP 线段树合并)

    BZOJ LOJ 令\(f[i][j]\)表示以\(i\)为根的子树,权值\(j\)作为根节点的概率. 设\(i\)的两棵子树分别为\(x,y\),记\(p_a\)表示\(f[x][a]\),\(p_ ...

  9. [BZOJ5461][LOJ#2537[PKUWC2018]Minimax(概率DP+线段树合并)

    还是没有弄清楚线段树合并的时间复杂度是怎么保证的,就当是$O(m\log n)$吧. 这题有一个显然的DP,dp[i][j]表示节点i的值为j的概率,转移时维护前缀后缀和,将4项加起来就好了. 这个感 ...

随机推荐

  1. `Facebook.Unity.Settings' has already been imported error solution

    after import facebook sdk to unity, i get the '`Facebook.Unity.Settings' has already been imported' ...

  2. node-redis使用记录

    redis的高速存取性能让人印象深刻,虽然是分布式存储,但相比本地内存,性能毫不逊色. 之所以能做到这点,是由于redis的“单线程,多路复用IO”,同一时刻只有一个操作在进行. 而且多次建立从red ...

  3. centos7系统配置系统用户基于ssh的google身份验证

    最近也是服务器各种被入侵,所以在安全上,要万分注意,特此记录,借助google的身份验证插件,获取动态验证码完成ssh登陆. OS: centos7 安装配置: 1. 安装epel源 yum -y i ...

  4. hdu1527取石子游戏(威佐夫博弈)

    取石子游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  5. HTML 常见的 DOCTYPE 声明

    <!DOCTYPE> 声明必须是 HTML 文档的第一行,位于 <html> 标签之前. <!DOCTYPE> 声明不是 HTML 标签:它是指示 web 浏览器关 ...

  6. 【SpringCloud】 第九篇: 服务链路追踪(Spring Cloud Sleuth)

    前言: 必需学会SpringBoot基础知识 简介: spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选. ...

  7. Unity与服务区交互数据

    Unity与服务区交互数据 Unity可能在用的时候使用到登陆等需要与服务器交互数据.今天尝试使用了WWW类和WWWForm类来实现Get请求与Post请求. 1.WWW Unity圣典解释: WWW ...

  8. hibernate.hbm2ddl.auto=update不能自动生成表结构

    在写上篇文章<spring整合springmvc和hibernate>的时候,曾遇到一个问题 INFO: Server startup in 8102 ms Hibernate: inse ...

  9. (原) MaterialEditor部- UmateriaEditor中 Node编译过程和使用(3)修正

    @author: 白袍小道 转载说明原处,爱护劳动 插件同步在GITHUB: DaoZhang_XDZ         说明 1.本篇是接着-----(原) MaterialEditor部- Umat ...

  10. Font Awesome 完美的图标字体

    好久没来,虽说鄙人的人气不咋地,但还是很想念自己这一亩二分田地. 近期用在平台开发中,看着设计师摆开阵势,准备大画图标,想着自己将会很KUBI拼凑css-sprite图片,接着写一大堆 class^= ...