[BZOJ5461][LOJ#2537[PKUWC2018]Minimax(概率DP+线段树合并)
还是没有弄清楚线段树合并的时间复杂度是怎么保证的,就当是$O(m\log n)$吧。
这题有一个显然的DP,dp[i][j]表示节点i的值为j的概率,转移时维护前缀后缀和,将4项加起来就好了。
这个感觉已经很难做到比$O(n^2)$更优的复杂度了,但我们要看到题目里有什么条件没用上:每个节点最多有2个儿子。
这个提醒我们可以用启发式合并,据说splay可以做,但我们可以考虑一下线段树合并做法。
仍然采用上面的转移方程,这里线段树上的一个节点T[x]表示x表示的区间[L,R]最终成为当前子树的根的值的概率,那么答案显然可以通过最终线段树上每个叶子节点统计。现在难点就在于如何统计。
考虑某个左子树的动态开店权值线段树上某个节点x表示的区间[L,R]最后成为根rt的值的概率,它是由p[rt]*(右子树的值小于R的概率)+(1-p[rt])*(右子树的值小于L的概率),这个其实是可以在merge的过程中递归下去累加的。
具体做法是:merge(x,y,sx,sy)表示合并线段树节点x和y(显然这里x和y分属左右子树,表示的是同一个权值区间),那么我们每次将这一层的信息累加进去,接着递归下去即可。当我们发现只存在一棵子树了(设为x),那么这棵子树的概率要乘上sy。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rep(i,l,r) for (int i=l; i<=r; i++)
typedef long long ll;
using namespace std; const int N=,M=,g=,mod=;
int n,nd,p,tot,w[N],rt[N],fa[N],son[N][],b[N],s[M],tag[M],ls[M],rs[M]; void put(int x,int k){ s[x]=1ll*s[x]*k%mod; tag[x]=1ll*tag[x]*k%mod; }
void push(int x){ if (tag[x]!=) put(ls[x],tag[x]),put(rs[x],tag[x]),tag[x]=; } void init(int &x,int L,int R,int pos){
x=++nd; s[x]=tag[x]=;
if (L==R) return;
int mid=(L+R)>>;
if (pos<=mid) init(ls[x],L,mid,pos);
else init(rs[x],mid+,R,pos);
} int merge(int x,int y,int sx,int sy){
if (!y){ put(x,sy); return x; }
if (!x){ put(y,sx); return y; }
push(x); push(y);
int x0=s[ls[x]],y0=s[ls[y]],x1=s[rs[x]],y1=s[rs[y]];
ls[x]=merge(ls[x],ls[y],(sx+1ll*(-p)*x1)%mod,(sy+1ll*(-p)*y1)%mod);
rs[x]=merge(rs[x],rs[y],(sx+1ll*p*x0)%mod,(sy+1ll*p*y0)%mod);
s[x]=(s[ls[x]]+s[rs[x]])%mod; return x;
} int solve(int x){
if (!son[x][]) { init(rt[x],,tot,lower_bound(b+,b+tot+,w[x])-b); return rt[x]; }
int l=solve(son[x][]); if (!son[x][]) return l;
int r=solve(son[x][]); p=1ll*g*w[x]%mod; return merge(l,r,,);
} int dfs(int x,int L,int R){
if (L==R) return 1ll*L*b[L]%mod*s[x]%mod*s[x]%mod;
int mid=(L+R)>>; push(x);
return (dfs(ls[x],L,mid)+dfs(rs[x],mid+,R))%mod;
} int main(){
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
scanf("%d",&n);
rep(i,,n) scanf("%d",&fa[i]),son[fa[i]][son[fa[i]][] ? : ]=i;
rep(i,,n){
scanf("%d",&w[i]); if (!son[i][]) b[++tot]=w[i];
}
sort(b+,b+tot+); printf("%d\n",(dfs(solve(),,tot)+mod)%mod);
return ;
}
[BZOJ5461][LOJ#2537[PKUWC2018]Minimax(概率DP+线段树合并)的更多相关文章
- LOJ2537. 「PKUWC2018」Minimax【概率DP+线段树合并】
LINK 思路 首先暴力\(n^2\)是很好想的,就是把当前节点概率按照权值大小做前缀和和后缀和然后对于每一个值直接在另一个子树里面算出贡献和就可以了,注意乘上选最大的概率是小于当前权值的部分,选最小 ...
- BZOJ.5461.[PKUWC2018]Minimax(DP 线段树合并)
BZOJ LOJ 令\(f[i][j]\)表示以\(i\)为根的子树,权值\(j\)作为根节点的概率. 设\(i\)的两棵子树分别为\(x,y\),记\(p_a\)表示\(f[x][a]\),\(p_ ...
- 【洛谷5298】[PKUWC2018] Minimax(树形DP+线段树合并)
点此看题面 大致题意: 有一棵树,给出每个叶节点的点权(互不相同),非叶节点\(x\)至多有两个子节点,且其点权有\(p_x\)的概率是子节点点权较大值,有\(1-p_x\)的概率是子节点点权较小值. ...
- [PKUWC2018]Minimax [dp,线段树合并]
好妙的一个题- 我们设 \(f_{i,j}\) 为 \(i\) 节点出现 \(j\) 的概率 设 \(l = ch[i][0] , r = ch[i][1]\) 即左儿子右儿子 设 \(m\) 为叶子 ...
- BZOJ5461 PKUWC2018Minimax(概率期望+线段树合并+动态规划)
离散化后,容易想到设f[i][j]为i节点权值为j的概率,不妨设j权值在左子树,则有f[i][j]=f[lson][j](pi·f[rson][1~j]+(1-pi)·f[rson][j~m]). 考 ...
- 【pkuwc2018】 【loj2537】 Minmax DP+线段树合并
今年年初的时候参加了PKUWC,结果当时这一题想了快$2h$都没有想出来.... 哇我太菜啦.... 昨天突然去搜了下哪里有题,发现$loj$上有于是就去做了下. 结果第一题我5分钟就把所有细节都想好 ...
- P6847-[CEOI2019]Magic Tree【dp,线段树合并】
正题 题目链接:https://www.luogu.com.cn/problem/P6847 题目大意 \(n\)个点的一棵树上,每个时刻可以割掉一些边,一些节点上有果实表示如果在\(d_i\)时刻这 ...
- CTSC 2017 游戏[概率dp 线段树]
小 R 和室友小 B 在寝室里玩游戏.他们一共玩了 $n$ 局游戏,每局游戏的结果要么是小 R 获胜,要么是小 B 获胜. 第 $1$ 局游戏小 R 获胜的概率是 $p_1$,小 B 获胜的概率是 $ ...
- [tsA1490][2013中国国家集训队第二次作业]osu![概率dp+线段树+矩阵乘法]
这样的题解只能舔题解了,,,qaq 清橙资料里有.. #include <iostream> #include <cstdio> #include <cstdlib> ...
随机推荐
- [NOI2002] 银河英雄传说 (带权并查集)
题目描述 公元五八○一年,地球居民迁至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山压顶 ...
- angularjs的验证信息的写法
<div ng-messages="alarmDelayForm.alarmRuleName.$error" role="alert"> <d ...
- domReady的兼容性实现方法
一.为何要实现domReay方法? 举例: <!DOCTYPE html> <html lang="en"> <head> <meta c ...
- 知问前端——日历UI(三)
datepicker日期选择选项 属性 默认值/类型 说明 minDate 无/对象.字符串或数值 日历中可以选择的最小日期 maxDate 无/对象.字符串或数值 日历中可以选择的最大日期 defa ...
- 【转载】字符串最小表示法-O(n)算法
原博客链接:http://blog.csdn.net/zy691357966/article/details/39854359 未授权,侵权删. 因为这篇博客写得真好..转载了.. 红色的字是原博主写 ...
- 之江学院第0届校赛 qwb与支教 (容斥公式)
description qwb同时也是是之江学院的志愿者,暑期要前往周边地区支教,为了提高小学生的数学水平.她把小学生排成一排,从左至右从1开始依次往上报数. 玩完一轮后,他发现这个游戏太简单了.于是 ...
- Codeforces 940F Machine Learning 带修改莫队
题目链接 题意 给定一个长度为\(n\)的数组\(a\),\(q\)个操作,操作分两种: 对于区间\([l,r]\),询问\(Mex\{c_0,c_1,c_2,⋯,c_{10^9}\}\),其中\(c ...
- ANDROID开发笔记(一)
manifest, 英['mænɪfest] vt. 显示,表明;证明;使显现 adj. 明白的,明显的 n. 货单,旅客名单 wrap_content, 根据实际内容调整 原来新版的ADB已经支 ...
- Kuangbin 带你飞 数位DP题解
以前一直不知道该咋搞这个比较好. 感觉推起来那个数字好麻烦.后来有一种比较好的写法就是直接的DFS写法.相应的ismax表示当前位是否有限制. 数位DP也是有一种类似模版的东西,不过需要好好理解.与其 ...
- JQ子页面对父页面的元素进行操作
需要加上parent.document,才能找到父页面的元素 如: $("#tabs", parent.document).click();