题目链接

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;
}

最新文章

  1. Android开发6:Service的使用(简单音乐播放器的实现)
  2. easyui 下拉树改造
  3. iOS开发——网络使用技术OC篇&amp;网络爬虫-使用正则表达式抓取网络数据
  4. 对MySql查询缓存及SQL Server过程缓存的理解及总结
  5. [CareerCup] 2.2 Kth to Last Element of Linked List 链表的倒数第k个元素
  6. timus 1210 Kind Spirits(最短路)(动态规划)
  7. Android的px、dip、sp的区别
  8. Server.MapPath()获取绝对路径
  9. bzoj1001
  10. C#中调用存储过程
  11. zepto.js 处理Touch事件(实例)
  12. 从头开始-01.C语言环境测试
  13. Quartz2D裁剪圆形头像
  14. 测试员浅谈App测试的重点
  15. Linux: 查看软件安装路径
  16. tpshop使用自带极光推送
  17. ThreadLocal中的WeakReference
  18. js中url跳转问题
  19. github远程仓库初始化配置
  20. Vue.js 动画

热门文章

  1. HTML之微信全屏播放视频
  2. 【luoguP1414]】又是毕业季II
  3. (10)Go结构体struct
  4. 【cf比赛练习记录】Codeforces Round #579 (Div. 3)
  5. jmap -heap 查看堆内存
  6. Jmeter命令行运行配置环境变量
  7. 自己搭建gitlab服务,组员不能上传代码
  8. String字符串与其他格式(int、boolean等八大数据类型)的相互转换
  9. Eclipse创建Maven父子项目
  10. AnnotatedElementUtils.findMergedAnnotation作用