Luogu5298 [PKUWC2018]Minimax

太久没写博客了,过来水一发。感觉自己推式子的功力还不够。。。

题目链接:洛谷


首先我们想到,考虑每个叶节点的权值为根节点权值的概率。首先要将叶节点权值离散化。

假设现在是$x$节点,令$f_i,g_i$分别表示左/右节点的权值$=i$的概率。

若$w_x$来自于左儿子,则

$$P(w_x=i)=f_i*(p_x*\sum_{j=1}^{i-1}g_j+(1-p)*\sum_{j=i+1}^mg_j)$$

右儿子也是一样的。

所以在转移的时候需要顺便维护$f,g$的前/后缀和。

但是我们发现这样直接跑是$O(n^2)$的,肯定不行,但是每个节点的所有dp值都只依赖于两个儿子,而且区间乘法是可以使用lazy_tag的,所以可以使用线段树合并

(等会儿,好像之前并没有写过。。。)

线段树合并就是对于值域线段树,合并的时候如果两棵树都有这个节点,那么就递归下去,否则直接按照上面的式子转移。

$f,g$的前/后缀和也可以放在参数里面顺便维护了。

 1 #include<bits/stdc++.h>
 2 #define Rint register int
 3 using namespace std;
 4 typedef long long LL;
 5 const int N = 300003, mod = 998244353, inv = 796898467;
 6 int n, v[N], tot, p[N], fa[N], head[N], to[N], nxt[N];
 7 inline void add(int a, int b){
 8     static int cnt = 0;
 9     to[++ cnt] = b; nxt[cnt] = head[a]; head[a] = cnt;
10 }
11 int root[N], ls[N << 5], rs[N << 5], seg[N << 5], tag[N << 5], cnt, ans;
12 inline void pushdown(int x){
13     if(x && tag[x] != 1){
14         if(ls[x]){
15             seg[ls[x]] = (LL) seg[ls[x]] * tag[x] % mod;
16             tag[ls[x]] = (LL) tag[ls[x]] * tag[x] % mod;
17         }
18         if(rs[x]){
19             seg[rs[x]] = (LL) seg[rs[x]] * tag[x] % mod;
20             tag[rs[x]] = (LL) tag[rs[x]] * tag[x] % mod;
21         }
22         tag[x] = 1;
23     }
24 }
25 inline void change(int &x, int L, int R, int pos){
26     if(!x) tag[x = ++ cnt] = 1;
27     pushdown(x);
28     ++ seg[x];
29     if(seg[x] >= mod) seg[x] = 0;
30     if(L == R) return;
31     int mid = L + R >> 1;
32     if(pos <= mid) change(ls[x], L, mid, pos);
33     else change(rs[x], mid + 1, R, pos);
34 }
35 inline int merge(int lx, int rx, int L, int R, int pl, int pr, int sl, int sr, int P){
36     if(!lx && !rx) return 0;
37     int now = ++ cnt, mid = L + R >> 1; tag[now] = 1;
38     pushdown(lx); pushdown(rx);
39     if(!lx){
40         int v = ((LL) P * sl + (mod + 1ll - P) * sr) % mod;
41         seg[now] = (LL) seg[rx] * v % mod;
42         tag[now] = (LL) tag[rx] * v % mod;
43         ls[now] = ls[rx]; rs[now] = rs[rx];
44         return now;
45     }
46     if(!rx){
47         int v = ((LL) P * pl + (mod + 1ll - P) * pr) % mod;
48         seg[now] = (LL) seg[lx] * v % mod;
49         tag[now] = (LL) tag[lx] * v % mod;
50         ls[now] = ls[lx]; rs[now] = rs[lx];
51         return now;
52     }
53     ls[now] = merge(ls[lx], ls[rx], L, mid, pl, (pr + seg[rs[rx]]) % mod, sl, (sr + seg[rs[lx]]) % mod, P);
54     rs[now] = merge(rs[lx], rs[rx], mid + 1, R, (pl + seg[ls[rx]]) % mod, pr, (sl + seg[ls[lx]]) % mod, sr, P);
55     seg[now] = (seg[ls[now]] + seg[rs[now]]) % mod;
56     return now;
57 }
58 inline void getans(int x, int L, int R){
59     pushdown(x);
60     if(L == R){
61         ans = (ans + (LL) seg[x] * seg[x] % mod * v[L] % mod * L % mod) % mod;
62         return;
63     }
64     int mid = L + R >> 1;
65     getans(ls[x], L, mid);
66     getans(rs[x], mid + 1, R);
67 }
68 inline void dfs(int x){
69     if(!head[x]){
70         change(root[x], 1, n, p[x]);
71         return;
72     }
73     for(Rint i = head[x];i;i = nxt[i]){
74         dfs(to[i]);
75         if(!root[x]) root[x] = root[to[i]];
76         else root[x] = merge(root[x], root[to[i]], 1, n, 0, 0, 0, 0, p[x]);
77     }
78 }
79 int main(){
80     scanf("%d", &n);
81     for(Rint i = 1;i <= n;i ++){
82         scanf("%d", fa + i);
83         if(fa[i]) add(fa[i], i);
84     }
85     for(Rint i = 1;i <= n;i ++){
86         scanf("%d", p + i);
87         if(head[i]) p[i] = (LL) p[i] * inv % mod;
88         else v[++ tot] = p[i];
89     }
90     sort(v + 1, v + tot + 1);
91     for(Rint i = 1;i <= n;i ++)
92         if(!head[i]) p[i] = lower_bound(v + 1, v + tot + 1, p[i]) - v;
93     dfs(1);
94     getans(root[1], 1, n);
95     printf("%d", ans);
96 }
luogu5369

 

转载于:https://www.cnblogs.com/AThousandMoons/p/10893829.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/362630.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js封装常用函数

自己封装函数时&#xff0c;参数最好不要超过3个&#xff0c;若要超过&#xff0c;可以用数组或者对象&#xff1b; 1. 利用&#xff08;Math.random&#xff09;写指定范围的随机数 2. 补零 3. 数组去重 4. 排序 5. 敏感词过滤 6. 判断数组中是否存在某一条数据&#xff0c;结…

JPA教程–在Java SE环境中设置JPA

JPA代表Java Persistence API&#xff0c;它基本上是一个规范&#xff0c;描述了一种将数据持久存储到持久存储&#xff08;通常是数据库&#xff09;中的方法。 我们可以将其视为类似于Hibernate的 ORM工具的东西&#xff0c;除了它是Java EE规范的正式组成部分&#xff08;并…

滚动条造成页面抖动问题

总结&#xff1a; 若用到 margin:0 auto; 使页面居中&#xff0c;若部分页面出现滚动条&#xff0c;滚动条默认有 20px&#xff0c;这样会造成页面抖动&#xff1b; 解决办法&#xff1a;参考 1. html{overflow:scoll;} 让页面一直显示滚动条。 overflow 的几个属性值&#xf…

ie 浏览器布局中的 offset

出现原因&#xff1a; 此处的offset的值表示的是盒子模型经过计算后的实际偏移量&#xff0c;通常是margin及定位偏移量之和&#xff08;flex布局导致的偏移也会计算在内&#xff09;。在此处也无需消除。 解决办法&#xff1a; 父元素设置宽高。设置margin为负数&#xff0…

MySQL集群(PXC)入门

一、学习动机 伴随互联网行业的兴起&#xff0c;越来越多的领域需要相应的技术方案&#xff0c;比如&#xff1a;打出软件、电商平台、直播平台、电子支付、媒体社交。 身边常见的&#xff0c;校园出成绩那一年&#xff0c;我们会感觉网站异常的卡顿&#xff0c;因为访问人数太…

滚动条那些事

一、滚动条样式 1. ie8浏览器 名称描述scrollbar-arrow-color三角箭头的颜色scrollbar-face-color立体滚动条的颜色&#xff08;包括箭头部分的背景色&#xff09;scrollbar-3dlight-color立体滚动条亮边的颜色scrollbar-highlight-color滚动条的高亮颜色&#xff08;左阴影&…

Javascript高级程序设计第二版第十四章--异常--笔记

chaepter 14 错误异常分享。 其实主要是就是try{}catch(error){} finally{}这个语句的理解。主要一点&#xff1a;finally 在 return 之后 运行。这跟java里边的如出一辙。 比如&#xff1a;try{return1;}catch(error){return2;} finally{return0;}返回 return 0;然后接着就是 …

HTML引入vue.js,在ie浏览器中不显示

因为只有两个页面&#xff0c;所以我没有用 vue-cli 搭框架&#xff0c;直接在 HTML 中引入vue.js 文件。发现其他浏览器都能正常显示&#xff0c;ie 下显示不正常&#xff0c;而且还报错&#xff0c;错误信息如下&#xff1a; 原因&#xff1a; 主要是因为 ie 不支持 ES6 的语…

具有Infinispan的聚集幂等消费者模式

我创建了一个小项目 &#xff0c;该项目展示了如何将JBoss Infinispan与Apache Camel和幂等消费者模式一起使用&#xff0c;以确保消息不会在集群环境中被处理两次。 假设您有一个应用程序&#xff0c;该应用程序必须通过将其部署在多个容器上才能轻松扩展。 但是应用程序必须…

基于 vue 的验证码组件

登录页面有个验证码&#xff0c;暂时没用到后台&#xff0c;在网上找了两个博客&#xff0c;记录一下。 一、直接写&#xff08;参考-UIEngineer&#xff09; 这个样式比较简单&#xff0c;直接在需要验证码的地方添加就行了。如果这个页面比较复杂&#xff0c;用组件会比较好…

在 HTML 中引入 vue.js 写页面

突然说要写两个页面&#xff08;只有两个页面&#xff0c;不是一个完整的项目。。&#xff09;&#xff0c;有点懵&#xff0c;不知道从哪下手&#xff0c;而且只对 vue 熟悉那么一丢丢&#xff0c;其他框架不是很熟悉。但是没办法鸭&#xff0c;只能硬着头皮去做了&#xff01…

Mschart图表制作

首先一次安装这三个 &#xff08;1&#xff09;.Microsoft .NET Framework 3.5 的 Microsoft 图表控件 &#xff08;2&#xff09;.Microsoft .NET Framework 3.5 语言包的 Microsoft 图表控件 &#xff08;3&#xff09;.Microsoft Chart Controls Add-on for Microsoft Visua…

vue打包后,font格式错误

本地测试没有问题&#xff0c;项目打包以后&#xff0c;浏览器打开控制台&#xff0c;提示font格式错误&#xff1a; 把我的双引号给去掉了。。。-^- 不开心。 解决办法&#xff1a; 1. 把 font: 字体粗细 字体大小/行高 "字体样式"; 分开来写。 改成&#xff1a;…

html笔记(四)弹性盒+响应式

大标题小节一、弹性盒1. 标准盒模型和怪异盒模型2. 弹性盒dipalay3. 与display配合使用的其他属性4. 弹性盒的对齐方式5. 弹性盒的默认特性二、响应式布局1. 媒体查询2. 怎样使用媒体查询3. 优缺点以及使用场景4. Meta 标签的定义5. 常见的属性操作三、多列布局四、移动端布局1…

享受Android应用程序的Java技术盛宴

Java™ 语言是 Android 开发人员所选的工具。Android 运行时使用自己的虚拟机Dalvik&#xff0c;这并不是多数程序开发人员使用的普通Java 虚拟机。Dalvik支持Java 编程语言的大部分功能——但并不是全部。在本文中&#xff0c;您将学习高级Java功能及其如何在Android中实现。这…

echarts地图在ie浏览器上不显示

前面是安装及上手教程&#xff0c;参考了彩色泡泡 和 winne雪 的博客。 如果已经写好了&#xff0c;可以直接跳到 问题总结。 1. npm install echarts --save 2. 在 main.js 中 import echarts from echarts; Vue.prototype.$echarts echarts;3. 在页面上 import china fr…

虚拟主机上快速安装kail

官方文档的筛选 【1】Kali Linux是什么? Kali Linux是一个高级渗透测试和安全审计Linux发行版. Kali Linux 特性 Kali是BackTrack Linux完全遵循Debian开发标准的完整重建.全新的目录框架、复查并打包所有工具、还为VCS建立了Git 树. 超过300个渗透测试工具: 复查了BackTrack里…

Java并发教程–线程之间的可见性

当在不同线程之间共享对象的状态时&#xff0c;除了原子性外&#xff0c;其他问题也会发挥作用。 其中之一是可见性。 关键事实是&#xff0c;如果没有同步&#xff0c;则不能保证指令按照它们在源代码中出现的顺序执行。 这不会影响单线程程序中的结果&#xff0c;但是&#…

让element-ui的输入框聚焦的4种方式

方法一、绑定ref 方法二、通过自定义事件中的事件对象 $event&#xff0c;找到input 方法三、使用自定义指令 方法四、使用原生input 方法一、绑定ref——参考yiyueqinghui <el-input v-model"form.name" ref"name"></el-input> this.$refs.n…

控制台打印三角形、菱形

一、 打印三角形 要求&#xff1a; 打印如下类似的三角形 * *** ***** ******* 效果&#xff1a;思路&#xff1a; &#xff08;1&#xff09; 空格每往下一层少一个。 &#xff08;2&#xff09; *是奇数数列&#xff0c;&#xff08;i – 1&#xff09;* 2 1 核心代码&#…