题目

Zeit und Raum trennen dich und mich.

时空将你我分开。B 君在玩一个游戏,这个游戏由 n 个灯和 n 个开关组成,给定这 n 个灯的初始状态,下标为

从 1 到 n 的正整数。每个灯有两个状态亮和灭,我们用 1 来表示这个灯是亮的,用 0 表示这个灯是灭的,游戏

的目标是使所有灯都灭掉。但是当操作第 i 个开关时,所有编号为 i 的约数(包括 1 和 i)的灯的状态都会被

改变,即从亮变成灭,或者是从灭变成亮。B 君发现这个游戏很难,于是想到了这样的一个策略,每次等概率随机

操作一个开关,直到所有灯都灭掉。这个策略需要的操作次数很多, B 君想到这样的一个优化。如果当前局面,

可以通过操作小于等于 k 个开关使所有灯都灭掉,那么他将不再随机,直接选择操作次数最小的操作方法(这个

策略显然小于等于 k 步)操作这些开关。B 君想知道按照这个策略(也就是先随机操作,最后小于等于 k 步,使

用操作次数最小的操作方法)的操作次数的期望。这个期望可能很大,但是 B 君发现这个期望乘以 n 的阶乘一定

是整数,所以他只需要知道这个整数对 100003 取模之后的结果。

输入格式

第一行两个整数 n, k。

接下来一行 n 个整数,每个整数是 0 或者 1,其中第 i 个整数表示第 i 个灯的初始情况。

1 ≤ n ≤ 100000, 0 ≤ k ≤ n;

输出格式

输出一行,为操作次数的期望乘以 n 的阶乘对 100003 取模之后的结果。

输入样例

4 0

0 0 1 1

输出样例

512

题解

为使操作次数最少,因为小的不能影响大的,那么从大的开始关闭,要关就一定关,因为往前没有灯可以关闭当前灯,所以是正确的

这样一枚举就是\(O(nlogn)\),预处理出了初始局面所需步数

然后就期望dp

期望dp一般设为当前状态到目标状态或者下一个状态的期望步数

我们设\(f[i]\)表示还剩\(i\)个操作就完成的情况下,到剩余\(i - 1\)个操作就完成所需要的操作期望次数

我们有\(\frac{i}{n}\)的概率操作正确

另有\(\frac{n - i}{n}\)的概率操作失败,此时我们就相当于多了一个操作撤回这次失败,就回到了\(f[i + 1]\)

所以我们有

\[f[i] = \frac{i}{n} + \frac{n - i}{n} * (1 + f[i + 1] + f[i])
\]

化简得

\[f[i] = \frac{n}{i} + \frac{n - i}{i} * f[i + 1]
\]

递推一下就可以算出\(f[i]\)了

由于还剩\(k\)步开始直接操作\(k\)步结束,我们令\(f[1...k] = 1\)

如果初始局面需要步数为\(m\)

\[ans = \sum\limits_{i = 1}^{m} f[i]
\]

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 100005,maxm = 100005,INF = 1000000000,P = 100003;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int f[maxn],shut[maxn],a[maxn],inv[maxn],n,k,need;
int main(){
n = read(); k = read();
REP(i,n) a[i] = read();
for (int i = n; i; i--){
for (int j = i + i; j <= n; j += i)
if (shut[j]) a[i] ^= 1;
if (a[i]) shut[i] = true,need++;
}
inv[0] = inv[1] = 1;
for (int i = 2; i <= n; i++) inv[i] = 1ll * (P - P / i) * inv[P % i] % P;
f[n] = 1;
for (int i = n - 1; i; i--){
f[i] = (1ll * n * inv[i] % P + 1ll * (n - i) * inv[i] % P * f[i + 1] % P) % P;
}
for (int i = 1; i <= k; i++) f[i] = 1;
int ans = 0;
for (int i = 1; i <= need; i++) ans = (ans + f[i]) % P;
for (int i = 1; i <= n; i++) ans = 1ll * ans * i % P;
printf("%d\n",ans);
return 0;
}

BZOJ4872 [六省联考2017]分手是祝愿 【期望dp】的更多相关文章

  1. [BZOJ4872][六省联考2017]分手是祝愿(期望DP)

    4872: [Shoi2017]分手是祝愿 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 516  Solved: 342[Submit][Statu ...

  2. [六省联考2017]分手是祝愿 期望DP

    表示每次看见期望的题就很懵逼... 但是这题感觉还是值得一做,有可借鉴之处 要是下面这段文字格式不一样的话(虽然好像的确不一样,我也不知道为什么,是直接从代码里面复制出来的,因为我一般都是习惯在代码里 ...

  3. P3750 [六省联考2017]分手是祝愿 期望DP

    \(\color{#0066ff}{ 题目描述 }\) Zeit und Raum trennen dich und mich. 时空将你我分开. B 君在玩一个游戏,这个游戏由 \(n\) 个灯和 ...

  4. [六省联考2017]分手是祝愿——期望DP

    原题戳这里 首先可以确定的是最优策略一定是从大到小开始,遇到亮的就关掉,因此我们可以\(O(nlogn)\)的预处理出初始局面需要的最小操作次数\(tot\). 然后容(hen)易(nan)发现即使加 ...

  5. bzoj千题计划266:bzoj4872: [六省联考2017]分手是祝愿

    http://www.lydsy.com/JudgeOnline/problem.php?id=4872 一种最优解是 从大到小灯有亮的就灭掉 最优解是唯一的,且关灯的顺序没有影响 最优解 对每个开关 ...

  6. [BZOJ4872][六省联考2017]分手是祝愿

    BZOJ Luogu sol 首先发现肯定有解,又因为每个位置至多操作一次,所以最优解一定是在\([0,n]\)之间 有一种可以在\(O(\sum_{i=1}^{n}\lfloor\frac{n}{i ...

  7. BZOJ 4872 luogu P3750 [六省联考2017]分手是祝愿

    4872: [Shoi2017]分手是祝愿 Time Limit: 20 Sec  Memory Limit: 512 MB[Submit][Status][Discuss] Description ...

  8. [bzoj4872] [洛谷P3750] [六省联考2017] 分手是祝愿

    Description Zeit und Raum trennen dich und mich. 时空将你我分开. \(B\) 君在玩一个游戏,这个游戏由 \(n\) 个灯和 \(n\) 个开关组成, ...

  9. luoguP3750 [六省联考2017]分手是祝愿 概率期望DP + 贪心

    ...........真的神状态了,没办法去想的状态................... 考试的时候选择$50$分贪心+$15$分状压吧,别的点就放弃算了........ 令$f[i]$表示从最小步 ...

随机推荐

  1. 2018.5.22 Oracle安装配置在虚拟机中外部电脑连接服务

    1.拷贝老师的集成文件(win系统和oracle服务) 2.安装虚拟机,并且打开镜像文件 3.启动监听程序(实例服务[自动].监听服务) 4.查看虚拟机ip,此ip要主机ip在同一个网段 5.检查虚拟 ...

  2. python_8_guess

    #python3和2都可以 #方法1 age_of_oldboy=56 count=0 while True: if count==3: break guess_age=int(input('gues ...

  3. [转] 防止js全局变量污染方法总结

    javaScript 可以随意定义保存所有应用资源的全局变量.但全局变量可以削弱程序灵活性,增大了模块之间的耦合性.在多人协作时,如果定义过多的全局变量 有可能造成全局变量冲突,也就是全局变量污染问题 ...

  4. Mac 系统 + Chrome浏览器 网页前端出现中文文字反转或顺序错乱

    问题背景 React开发的系统,收到一个BUG反馈,*"号个人统计"文字不正确,应为"个人号统计"*. 收到BUG后,打开浏览器查验是什么情况,难道犯了最基本的 ...

  5. 软件杯python-flask遇到的坑有感!

    大三下,对于我考研的人来说,时间不要太紧张,参加软件杯也是系主任要求,题目是公共地点人流量的检测,个人还是个菜鸟,但是把遇到的一些大家可能不小心会出现的问题贴出来,困扰我很久,还没睡好觉!!! Que ...

  6. iOS多播Delegate类——GCDMulticastDelegate用法小结

    iOS中通常的delegate模式只能有一个被委托的对象,这样当需要有多个被委托的对象时,实现起来就略为麻烦,在开源库XMPPFramework中提供了一个GCDMulticastDelegate类, ...

  7. Windows 下编辑 hosts 文件

    hosts 文件目录: C:\WINDOWS\system32\drivers\etc\hosts hosts是一个没有扩展名的系统文件,可以用记事本等工具打开,其作用就是将一些常用的网址域名与其对应 ...

  8. 自动化运维工具——ansible剧本playbook(三)

    一.Playbook--Ansible剧本 playbook是由一个或多个 "play"组成的列表 play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的ta ...

  9. vue 项目中使用mock假数据实现前后端分离

    也是查了很多的资料,整理出来.实现了前后端的分离,用到的技术vue-cli,webpack,node,json-server.首先全局安装json-server cnpm i json-server ...

  10. ZendFramework-2.4 源代码 - 路由(类图)

    <?php return array( // console 模式 'console'=>array( 'router' => array( //.... ), ), // http ...