2023NOIP A层联测22 差后队列

挺有意思的期望题,题解做法应该是 DP,但是我又双叒写出奇怪的做法……

思路

除去最大值外的元素个数的倒数就是这一轮取到某个数的概率,而最大值是特殊的情况,在被替代之前或作为最后一个数被弹出之前,不参与计算。

对于操作 0 的输出和操作 1 的输出分开处理。

操作 1

设 \(f[i]\) 表示在执行第 \(i\) 个操作时可弹出数的期望大小。

1.加入操作

加入后不成为最大值,\(f[i]=f[i-1]+val[i]\)。

加入后成为最大值,\(f[i]=f[i-1]+mx\),然后更新 \(mx=val[i]\)。(\(mx\) 为最大值)

2.删除操作

设此时队列中除去最大值外元素个数为 \(has\)。

除最大值外每个元素被取到的概率 \(p=\frac{1}{has}\)。

此时期望取到的值 \(ans=p*f[i]\)。

更新 \(f[i]=f[i-1]-ans\)。

\(ans\) 为这一次操作的答案。

操作 0

不难发现,每个元素都有一个开始会被弹出的操作 1,和一定被弹出队列的操作 1。

设第 \(i\) 个弹出操作弹出每个树的概率是 \(p[i]\)。(除最大值外每一个数被等概率弹出,所以 \(p[i]\) 容易得到)

设第 \(i\) 个弹出操作是总操作中第 \(a[i]\) 个操作。

设第 \(u\) 个插入队列的数,可以被弹出的第一个操作 1 是总弹出操作第 \(st_u\) 个,一定会被弹出的操作 1 是总弹出操作的第 \(ed_u\) 个。

那么对于第 \(u\) 个插入的数。如果不是最大值,那么它在第 \(k\ (st_u \leq k \leq ed_u)\) 次操作被弹出的概率是 \(p_k\prod_{j=st_u}^{k-1}(1-p_j)\)。

给期望删除时间的贡献为 \(a_kp_k\prod_{j=st_i}^{k-1}(1-p_j)\)。

第 \(u\) 个插入的数被删除时间的期望为 \(ans_u=\sum_{i=st_u}^{ed_u} a_ip_i \prod_{j=st_u}^{i-1} (1-p_j)\)。

接下来要考虑如何 \(O(1)\) 的求这个式子。

设 \(s_i=a_ip_i\prod_{j=1}^{i-1}(1-p_j)\)。

又有 \(g_1=\frac{1}{1-p_1}\),\(g_i=g_{i-1}\frac{1}{1-p_i}\)。

所以 \(ans_u=\sum_{i=st_u}^{ed_u} s_ig_{st_u-1}=g_{st_u-1}\sum_{i=st_u}^{ed_u} s_i\)。

后面的 \(s_i\) 可以用前缀和 \(O(1)\) 求出。

而上面的数预处理都是 \(O(n)\) 或 \(O(n\log_2n)\)。

总时间复杂度 \(O(n\log_2n)\)。

可能会有点小常数。

CODE

#include<bits/stdc++.h>
using namespace std; #define mod 998244353
#define int long long const int maxn=1e6+5; struct node
{
int st,ed;
}point[maxn]; int cnt,n,has=-1,mx,smx;
int a[maxn],val[maxn],p[maxn],s[maxn],f[maxn],g[maxn],ans[maxn],sp[maxn],t[maxn],st[maxn],ed[maxn]; queue<int>que; int ksm(int x,int y)
{
int sum=1;
for(;y;y/=2,x=x*x%mod) if(y&1) sum=sum*x%mod;
return sum;
} signed main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++)
{
int op;
scanf("%lld",&op);
if(op==0)
{
scanf("%lld",&val[i]);
has++;
if(val[i]>mx)
{
f[i]=(f[i-1]+mx)%mod,mx=val[i],st[smx]=cnt+1;
if(smx) que.push(smx);
smx=i;
}
else f[i]=(f[i-1]+val[i])%mod,st[i]=cnt+1,que.push(i);
}
else
{
cnt++;
if(has)
{
p[cnt]=ksm(has,mod-2);
a[cnt]=i;
ans[i]=f[i-1]*p[cnt]%mod;
f[i]=(f[i-1]-ans[i]+mod)%mod;
}
else
{
p[cnt]=1;
a[cnt]=i;
ans[i]=mx;
ans[smx]=i;
mx=smx=0;
f[i]=0;
}
has--;
if(has==0) while(!que.empty()) ed[que.front()]=cnt,que.pop();
}
}
while(!que.empty()) ed[que.front()]=cnt,que.pop(); sp[0]=1;
for(int i=1;i<=cnt;i++) sp[i]=max(sp[i-1]*((1-p[i]+mod)%mod)%mod,1ll);
for(int i=1;i<=cnt;i++) s[i]=sp[i-1]*p[i]%mod*a[i]%mod,t[i]=(t[i-1]+s[i])%mod;
g[0]=1;
for(int i=1;i<=cnt;i++)
{
if(p[i]==1) g[i]=1;
else g[i]=g[i-1]*ksm((1-p[i]+mod)%mod,mod-2)%mod;
}
for(int i=1;i<=n;i++)
{
if(ans[i]||val[i]==0||ed[i]==0||st[i]==0||ed[i]<st[i]||ed[i]>cnt) continue;
ans[i]=(t[ed[i]]-t[st[i]-1]+mod)*g[st[i]-1]%mod;
}
for(int i=1;i<=n;i++) printf("%lld ",ans[i]);
}

还是挺浅显易懂的吧。

2023NOIP A层联测22 T2 差后队列的更多相关文章

  1. Java String Integer转换 练习:编程求字符串“100”和“150”按十进制数值做差后的结果以字符串形式输出。

    package com.swift; public class String_To_Integer_Test { public static void main(String[] args) { /* ...

  2. 弹出层提示,X秒后关闭

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD ...

  3. JQuery弹出层,点击按钮后弹出遮罩层,有关闭按钮

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...

  4. JQuery弹出层,点击按钮后弹出遮罩层,有关闭按钮【转】

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...

  5. 《统计学习方法》P179页10.22前向后向算法公式推导

  6. 优化后队列的实现(C语言实现)

    上一篇中的队列的定义与实现(C语言实现) 中.不管是顺序队列还是链式队列,在尾加和删除头部的操作时.总有一个时间复杂度让人不惬意. 比方在顺序队列中,删除头部的操作后,总要将后面全部的结点都向前移动一 ...

  7. 【WPF】修改数据层ViewModel后,UI界面未同步更新

    界面:WPF(MVVM)中将集合类控件ItemsControl的ItemsSource绑定到了ViewModel中的ObservableCollection列表,ItemsControl.ItemTe ...

  8. 人工神经网络,支持任意数量隐藏层,多层隐藏层,python代码分享

    http://www.cnblogs.com/bambipai/p/7922981.html------误差逆传播算法讲解 人工神经网络包含多种不同的神经网络,此处的代码建立的是多层感知器网络,代码以 ...

  9. osi7层模型及线程和进程

    端口的作用: 在同一台电脑上,为了让不同 的程序分离开来! http:网站默认端口是80 https:网站默认端口是443 osi七层模型: 1.应用层:软件 2.表示层:接收数据 3.会话:保持登录 ...

  10. MVC系列之二 Model层细解

    一.简介 在上一篇将MVC的时候,有很有朋友对简单三层的概念不是很熟悉,因此,今天进行简单三层的一个简单介绍,同时为理解MVC中的Model做知识累计. 传统的三层主要指的是UI层,BLL层,DAL层 ...

随机推荐

  1. MarginNote 4 内存泄露?

    在床上用电脑的时候突然发现电脑风扇呼呼响,一摸很烫,以为是被子把出风口堵住了,于是调整角度继续用.结果一段时间之后风扇还是狂转不停,然后收到了这样的提示.不看不知道一看吓一跳,MarginNote 4 ...

  2. Kubernetes-8:Deployment、DaemonSet、Job、CronJob等各控制器介绍及演示

    前文中也都已经提及过k8s都有哪些常用的控制器,本文对这些控制器进行细剖及演示一下 RS与RC与Deployment关联 RC主要作用就是用来确保容器应用副本数保持用户的期望值数目,即如果有pod异常 ...

  3. 深入理解Argo CD工作原理

    1. ArgoCD 的架构 ArgoCD 是一个 Kubernetes 原生的持续交付工具,它通过监控 Git 仓库中的应用定义来自动部署应用到 Kubernetes 集群.其核心架构由以下几个关键组 ...

  4. Qt 中实现异步散列器

    [写在前面] 在很多工作中,我们需要计算数据或者文件的散列值,例如登录或下载文件. 而在 Qt 中,负责这项工作的类为 QCryptographicHash. 关于 QCryptographicHas ...

  5. 深度学习模型训练的过程理解(训练集、验证集、测试集、batch、iteration、epoch、单步预测、多步预测、kernels、学习率)

    呜呜呜呜,感谢大佬学弟给我讲干货. 本来是讨论项目的,后面就跑偏讲论文模型了. 解答了我一直以来的疑问: 数据放模型里训练的过程. 假设我们有一个数据集26304条数据,假设设置模型读入1000条,如 ...

  6. pimp技法浅析--实现轻量级的面向接口编程

    pimp.hpp: #ifndef pimp_hpp #define pimp_hpp class CMyComponent{ public: CMyComponent(); ~CMyComponen ...

  7. 暑假集训CSP提高模拟18

    \[暑假集训CSP提高模拟 \ 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1 \] Very good problem, this make my news rotate. ...

  8. 异步解析文件报错 NoSuchFileException

    问题描述:同步上传解析文件超时,修改为异步解析后找不到 文件 java.nio.file.NoSuchFileException 原因:异步文件上传,主线程结束后,临时目录的文件会被清理掉,子线程此时 ...

  9. Nuxt.js 应用中的 app:suspense:resolve 钩子详解

    title: Nuxt.js 应用中的 app:suspense:resolve 钩子详解 date: 2024/10/6 updated: 2024/10/6 author: cmdragon ex ...

  10. 使用SourceTree管理仓库代码

    1.首先我们需要下载sourcetree,你可以去官网下载自己需要的版本. 2.安装完毕之后,我们需要获取ssh密钥与github关联上才能使用 按下面的操作开始执行.确定之后,会出现一个字符界面,输 ...