题目链接

LOJ:https://loj.ac/problem/2537

洛谷:https://www.luogu.org/problemnew/show/P5298

Solution

不定期诈尸

好久没敲代码了犯了好多sb错误


考虑一个暴力的\(dp\),首先这题只用到了权值的大小关系,所以我们先离散化,设\(f_{x,i}\)表示\(x\)点权值为\(i\)的概率。

转移很显然:

\[f_{x,i}=f_{ls,i}\left(\sum_{j=1}^{i-1}p_x\cdot f_{rs,j}+\sum_{j=i+1}^{m}(1-p_x)\cdot f_{rs,j}\right)+f_{rs,i}\left(\sum_{j=1}^{i-1}p_x\cdot f_{ls,j}+\sum_{j=i+1}^{m}(1-p_x)\cdot f_{ls,j}\right)
\]

就是枚举当前是选最大值还是最小值,前缀和优化可以做到\(O(n^2)\)。

然后我们开权值线段树维护这个东西,每次线段树合并,合并的时候处理前缀和来优化。

时间复杂度\(O(n\log ^2 n)\),空间复杂度\(O(n\log n)\)。

Code

#include<bits/stdc++.h>
using namespace std; void read(int &x) {
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
} void print(int x) {
if(x<0) putchar('-'),x=-x;
if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');} #define lf double
#define ll long long #define pii pair<int,int >
#define vec vector<int >
#define mid ((l+r)>>1) #define pb push_back
#define mp make_pair
#define fr first
#define sc second #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++) const int maxn = 4e5+10;
const int inf = 1e9;
const lf eps = 1e-8;
const int mod = 998244353; int qpow(int a,int x) {
int res=1;
for(;x;x>>=1,a=1ll*a*a%mod) if(x&1) res=1ll*res*a%mod;
return res;
} int n,son[maxn][2],w[maxn],m,p,b[maxn];
int ls[maxn<<5],rs[maxn<<5],rt[maxn],s[maxn<<5],tag[maxn<<5],seg; void push(int x,int c) {s[x]=1ll*s[x]*c%mod,tag[x]=1ll*tag[x]*c%mod;} void pushdown(int x) {
if(tag[x]!=1) push(ls[x],tag[x]),push(rs[x],tag[x]),tag[x]=1;
} void insert(int &x,int l,int r,int c) {
if(!x) x=++seg;s[x]=tag[x]=1;
if(l==r) return ;
if(c<=mid) insert(ls[x],l,mid,c);
else insert(rs[x],mid+1,r,c);
} int merge(int x,int y,int lsum=0,int rsum=0) {
if(!x) return push(y,lsum),y;
if(!y) return push(x,rsum),x;
int t=++seg;tag[t]=1;pushdown(x),pushdown(y);
int sl=s[ls[x]],sr=s[ls[y]]; // 注意这里递归的时候会被改掉,我就被坑了好久...
ls[t]=merge(ls[x],ls[y],(lsum+1ll*(1-p+mod)*s[rs[x]]%mod)%mod,(rsum+1ll*(1-p+mod)*s[rs[y]]%mod)%mod);
rs[t]=merge(rs[x],rs[y],(lsum+1ll*p*sl%mod)%mod,(rsum+1ll*p*sr%mod)%mod);
s[t]=(s[ls[t]]+s[rs[t]])%mod;return t;
} int solve(int x) {
if(!son[x][0]) return insert(rt[x],1,m,lower_bound(b+1,b+m+1,w[x])-b),rt[x];
int l=solve(son[x][0]);
if(!son[x][1]) return l;
int r=solve(son[x][1]);p=w[x];
return merge(l,r);
} int calc(int x,int l,int r) {
if(!x) return 0;
if(l==r) return 1ll*l*b[l]%mod*s[x]%mod*s[x]%mod;
pushdown(x);
return (calc(ls[x],l,mid)+calc(rs[x],mid+1,r))%mod;
} int main() {
read(n);int I=qpow(10000,mod-2),x;
FOR(i,1,n) read(x),son[x][0]?son[x][1]=i:son[x][0]=i;
FOR(i,1,n) read(x),son[i][0]?w[i]=1ll*x*I%mod:b[++m]=w[i]=x;
sort(b+1,b+m+1);write(calc(solve(1),1,m));
return 0;
}

[LOJ2537] [PKUWC2018] Minimax的更多相关文章

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

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

  2. BZOJ5461: [PKUWC2018]Minimax

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

  3. LOJ2537:[PKUWC2018]Minimax——题解

    https://loj.ac/problem/2537 参考了本题在网上能找到的为数不多的题解. 以及我眼睛瞎没看到需要离散化,还有不开longlong见祖宗. ——————————————————— ...

  4. 题解-PKUWC2018 Minimax

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

  5. [PKUWC2018] Minimax

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

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

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

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

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

  8. 【洛谷5298】[PKUWC2018] Minimax(树形DP+线段树合并)

    点此看题面 大致题意: 有一棵树,给出每个叶节点的点权(互不相同),非叶节点\(x\)至多有两个子节点,且其点权有\(p_x\)的概率是子节点点权较大值,有\(1-p_x\)的概率是子节点点权较小值. ...

  9. Luogu P5298 [PKUWC2018]Minimax

    好劲的题目啊,根本没往线段树合并方面去想啊 首先每种权值都有可能出现,因此我们先排个序然后一个一个求概率 由于此时数的值域变成\([1,m]\)(离散以后),我们可以设一个DP:\(f_{x,i}\) ...

随机推荐

  1. 使用 css/less 动态更换主题色(换肤功能)

    前言 说起换肤功能,前端肯定不陌生,其实就是颜色值的更换,实现方式有很多,也各有优缺点 一.看需求是什么 一般来说换肤的需求分为两种: 1. 一种是几种可供选择的颜色/主题样式,进行选择切换,这种可供 ...

  2. 【区间DP】加分二叉树

    https://www.luogu.org/problemnew/show/P1040#sub 题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为 ...

  3. 微信小程序前端promise封装

    config.js const config = { base_url_api : "https://douban.uieee.com/v2/movie/", } export { ...

  4. @Aspect注解并不属于@Component的一种

    也就是一个类单纯如果只添加了@Aspect注解,那么它并不能被context:component-scan标签扫描到. 想要被扫描到的话,需要追加一个@Component注解

  5. 查看服务器内存、CPU、网络等占用情况的命令--汇总

    搭建测试环境过程中,需要对正在使用的aws服务器(实际这是一台虚拟出来的服务器),查看它在运行脚本,启动脚本时的内存,CPU,网络等使用情况 1.查看服务器cpu内核个数: -cat 每个物理cpu中 ...

  6. Dubbo+Zookeeper的简单入门案例

    1.1  Dubbo简介 Apache Dubbo是一款高性能的Java RPC框架.其前身是阿里巴巴公司开源的一个高性能.轻量级的开源Java RPC框架,可以和Spring框架无缝集成. 什么是R ...

  7. Hadoop(四)—— MapReduce

    一.Hadoop版本特性 MRv1 第一代计算框架,由编程模型和运行时环境两部分组成. 编程模型是,将数据进行map操作,然后进行reduce操作,最后将计算结果存储到HDFS中. 运行时环境是,由J ...

  8. Python语言编写BP神经网络

    Python语言编写BP神经网络 2016年10月31日 16:42:44 ldy944758217 阅读数 3135   人工神经网络是一种经典的机器学习模型,随着深度学习的发展神经网络模型日益完善 ...

  9. easyui datagrid怎么动态获取表头的列名及显示名称

    说明:目前使用easyui combobox多选属性,绑定的数据源是来自datagrid的表头的列名及显示名称 处理方法: //获取冻结的数据源并返回key,value格式数据 var GetFroz ...

  10. linux系统(centos6)的目录结构

    /bin:bin是Binary的缩写, 这个目录存放着最经常使用的命令. /boot:这里存放的是启动Linux时使用的一些核心文件,包括一些连接文件以及镜像文件. /dev :dev是Device( ...