「PKUWC2018」Minimax
题面
题解
线段树合并吼题啊
合并的时候要记一下$A$点权值小于$l$的概率和$A$点权值大于$r$的概率,对$B$点同样做
时空复杂度$\text O(nlogw)$,$w$为其中权值的最大值
代码
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#define RG register
#define file(x) freopen(#x".in", "r", stdin);freopen(#x".out", "w", stdout);
#define clear(x, y) memset(x, y, sizeof(x))
inline int read()
{
int data = 0, w = 1; char ch = getchar();
while(ch != '-' && (!isdigit(ch))) ch = getchar();
if(ch == '-') w = -1, ch = getchar();
while(isdigit(ch)) data = data * 10 + (ch ^ 48), ch = getchar();
return data * w;
}
const int Mod(998244353), Inv(796898467), maxn(300010), LIM((1 << 30) - 1);
inline int Add(int a, int b) { return (a + b) % Mod; }
int ans, cnt, son[2][maxn * 20], tag[maxn * 20], P[maxn * 20], cur, root[maxn];
inline int newNode()
{
tag[++cur] = 1; P[cur] = 0;
son[0][cur] = son[1][cur] = 0;
return cur;
}
inline void pushup(int x) { P[x] = Add(P[son[0][x]], P[son[1][x]]); }
inline void put_tag(int x, int p)
{
if(!x) return;
tag[x] = 1ll * tag[x] * p % Mod;
P[x] = 1ll * P[x] * p % Mod;
}
inline void pushdown(int x)
{
put_tag(son[0][x], tag[x]);
put_tag(son[1][x], tag[x]);
tag[x] = 1;
}
void calc(int x, int l = 0, int r = LIM)
{
if(!x) return;
if(l == r)
{
++cnt; ans = Add(ans, 1ll * cnt * P[x] % Mod * P[x] % Mod * l % Mod);
return;
}
pushdown(x);
int mid = (l + r) >> 1;
calc(son[0][x], l, mid);
calc(son[1][x], mid + 1, r);
}
void insert(int &x, int id, int l = 0, int r = LIM)
{
if(!x) x = newNode();
tag[x] = P[x] = 1;
if(l == r) return;
int mid = (l + r) >> 1;
if(id <= mid) insert(son[0][x], id, l, mid);
else insert(son[1][x], id, mid + 1, r);
}
int S[2][maxn], tot[maxn], W[maxn], n;
int merge(int a, int b, int pa, int pb, int pmax)
{
if(!a && !b) return 0;
if(!a) return put_tag(b, pa), b;
if(!b) return put_tag(a, pb), a;
pushdown(a), pushdown(b);
int pal = Add(pa, 1ll * P[son[1][a]] * Add(Mod - pmax, 1) % Mod),
pbl = Add(pb, 1ll * P[son[1][b]] * Add(Mod - pmax, 1) % Mod),
par = Add(pa, 1ll * P[son[0][a]] * pmax % Mod),
pbr = Add(pb, 1ll * P[son[0][b]] * pmax % Mod);
son[0][a] = merge(son[0][a], son[0][b], pal, pbl, pmax);
son[1][a] = merge(son[1][a], son[1][b], par, pbr, pmax);
return pushup(a), a;
}
void dfs(int x)
{
if(!tot[x]) return (void) (insert(root[x], W[x]));
W[x] = 1ll * W[x] * Inv % Mod;
for(RG int i = 0; i < tot[x]; i++) dfs(S[i][x]);
if(tot[x] == 1) root[x] = root[S[0][x]];
else root[x] = merge(root[S[0][x]], root[S[1][x]], 0, 0, W[x]);
}
int main()
{
#ifndef ONLINE_JUDGE
file(cpp);
#endif
n = read();
for(RG int i = 1, fa; i <= n; i++)
fa = read(), S[tot[fa]++][fa] = i;
for(RG int i = 1; i <= n; i++) W[i] = read();
dfs(1); calc(root[1]); printf("%d\n", ans);
return 0;
}
「PKUWC2018」Minimax的更多相关文章
- loj#2537. 「PKUWC2018」Minimax
题目链接 loj#2537. 「PKUWC2018」Minimax 题解 设\(f_{u,i}\)表示选取i的概率,l为u的左子节点,r为u的子节点 $f_{u,i} = f_{l,i}(p \sum ...
- LOJ2537. 「PKUWC2018」Minimax【概率DP+线段树合并】
LINK 思路 首先暴力\(n^2\)是很好想的,就是把当前节点概率按照权值大小做前缀和和后缀和然后对于每一个值直接在另一个子树里面算出贡献和就可以了,注意乘上选最大的概率是小于当前权值的部分,选最小 ...
- loj2537 「PKUWC2018」Minimax 【概率 + 线段树合并】
题目链接 loj2537 题解 观察题目的式子似乎没有什么意义,我们考虑计算出每一种权值的概率 先离散化一下权值 显然可以设一个\(dp\),设\(f[i][j]\)表示\(i\)节点权值为\(j\) ...
- 【LOJ】#2537. 「PKUWC2018」Minimax
题解 加法没写取模然后gg了QwQ,de了半天 思想还是比较自然的,线段树合并的维护方法我是真的很少写,然后没想到 很显然,我们有个很愉快的想法是,对于每个节点枚举它所有的叶子节点,对于一个叶子节点的 ...
- LOJ2537. 「PKUWC2018」Minimax [DP,线段树合并]
传送门 思路 首先有一个\(O(n^2)\)的简单DP:设\(dp_{x,w}\)为\(x\)的权值为\(w\)的概率. 假设\(w\)来自\(v1\)的子树,那么有 \[ dp_{x,w}=dp_{ ...
- Loj #2542. 「PKUWC2018」随机游走
Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...
- 「PKUWC2018」随机游走(min-max容斥+FWT)
「PKUWC2018」随机游走(min-max容斥+FWT) 以后题目都换成这种「」形式啦,我觉得好看. 做过重返现世的应该看到就想到 \(min-max\) 容斥了吧. 没错,我是先学扩展形式再学特 ...
- 「PKUWC2018」猎人杀
「PKUWC2018」猎人杀 解题思路 首先有一个很妙的结论是问题可以转化为已经死掉的猎人继续算在概率里面,每一轮一直开枪直到射死一个之前没死的猎人为止. 证明,设所有猎人的概率之和为 \(W\) , ...
- LOJ3044. 「ZJOI2019」Minimax 搜索
LOJ3044. 「ZJOI2019」Minimax 搜索 https://loj.ac/problem/3044 分析: 假设\(w(1)=W\),那么使得这个值变化只会有两三种可能,比\(W\)小 ...
随机推荐
- 2016424王启元 Exp6信息搜集与漏洞扫描
一.原理与实践说明 1.实践内容 本实践的目标是掌握信息搜集的最基础技能.具体有: 1.各种搜索技巧的应用 2.DNS IP注册信息的查询 3.基本的扫描技术:主机发现.端口扫描.OS及服务版本探测. ...
- 日常踩坑——Dev C++ pow()函数的坑
坑 Dev C++ pow()函数 那年冬天,显示屏前坐着如喽啰,那时候我含泪发誓,再也不用Dev. 蓝桥杯官网给提供的版本,没办法bug也得硬着头皮用. 16年蓝桥杯的第八题 四平方和定理: 在De ...
- C#获取路径问题
由于在写控制台的时候,不能获取到绝对的路径.(下面为学习内容) System.IO.Path类中有一些获取路径的方法,可以在控制台程序或者WinForm中根据相对路径来获取绝对路径 获取web物理路径 ...
- Nginx学习之从零搭建静态资源网站
前言 在某学习网站学习了nginx的安装和使用,以此文记录. 环境准备 安装在VMWare下的Centos虚拟机.由于我这是新装的虚拟机.所以很多插件都没有,这里干脆一次性安装上. wget ...
- jQuery.mobile.changePage的参数
选项 类型:对象 属性: allowSamePageTransition(默认值:假的) 类型:布尔 默认情况下,changePage()忽略请求更改为当前活动页面.将此选项设置为true,则允许该请 ...
- HDU 2307 贪心之活动安排问题
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2037 今年暑假不AC Time Limit: 2000/1000 MS (Java/Others) ...
- 创建DBLink----Oracle和mysql
Oracle: DROP PUBLIC DATABASE LINK NM_HN; CREATE PUBLIC DATABASE LINK NM_HN CONNECT TO XZXT IDENTIFIE ...
- 框架 Hibernate 2
持久化类百度百科 http://baike.baidu.com/link?url=gNus-8jhK0Mi401aIR-16YUAnWKzOJfeMagUV8_t5iG8235JyjMrmZPd7rI ...
- LeetCode39.组合总和 JavaScript
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的数字可以无限制重复被选 ...
- Objective-C 之深拷贝和浅拷贝
3月箴言 人的思想是了不起的,只要专注于某一项事业,就一定会做出使自己感到吃惊的成绩来.—— 马克·吐温 1.iOS中关于深拷贝和浅拷贝的概念 浅拷贝:浅拷贝并不拷贝对象本身,只是对指向对象的指针进行 ...