Description

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 取模之后的结果。

Input

第一行两个整数 n, k。

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

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

Output

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

Sample Input

4 0

0 0 1 1

Sample Output

512

Sol

作为一道联考省选题,覆盖知识点广,题目又着切合实际的背景,解法比较自然,给出题人点赞!

题确实挺好的,但是我太菜了模拟赛的时候直接模拟骗了80分......后来听了讲解才补的......

我们发现每个灯只用按一次,而每个灯的贡献又是独一无二的,所以需要按的灯的集合是固定的,每次我们只关心按的灯对于剩余步数的贡献,设\(f[i]\)表示还需要i步才能全部按灭的期望步数,则\(f[i]=\frac{i}{n}f[i-1]+\frac{n-i}{n}f[i+1]+1\),也就是分两种情况:按的灯在不在有用集合里面。

这个式子并不需要高斯消元,有两种做法:

1.因为f[0]是确定的,所以可以用回代法求出所有的值,时间复杂度\(O(n)\)。

2.设\(g[i]=f[i]-f[i-1]\),表示从需要i步到需要i-1步的期望次数,那么:

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

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

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

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

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

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

然后就可以\(O(n)\)计算了。

算出来以后特判一下\(n=k\)以及\(k>=tot\)的情况(tot为有用的灯集合大小),这样的情况下答案直接是tot。

否则答案\(=(\sum_{i=k+1}^{tot}g[i])+k\)。

Code

#include <bits/stdc++.h>
using namespace std;
int n,a[100005],f[100005],tot,K,fac=1,P=100003,ans;vector<int>e[100005];
int ksm(int a,int b){int res=1;for(;b;b>>=1,a=1ll*a*a%P) if(b&1) res=1ll*res*a%P;return res;}
int main()
{
for(int i=1;i<=P-3;i++) for(int j=i;j<=P-3;j+=i) e[j].push_back(i);
scanf("%d%d",&n,&K);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=n;i;i--)
{
if(a[i]) tot++;else continue;
for(int j=0;j<e[i].size();j++) a[e[i][j]]^=1;
}
for(int i=1;i<=n;i++) fac=1ll*fac*i%P;
for(int i=n;i;i--) f[i]=1ll*(n+1ll*(n-i)*f[i+1]%P)%P*ksm(i,P-2)%P;
if(K==n||K>=tot) ans=tot;
else for(int i=tot;i>K;i--) ans=(ans+f[i]+(i==tot?K:0))%P;
printf("%d\n",1ll*ans*fac%P);
}

【bzoj4872】[Shoi2017]分手是祝愿 期望dp的更多相关文章

  1. bzoj 4872: [Shoi2017]分手是祝愿 [期望DP]

    4872: [Shoi2017]分手是祝愿 题意:n个灯开关游戏,按i后i的约数都改变状态.随机选择一个灯,如果当前最优策略\(\le k\)直接用最优策略.问期望步数\(\cdot n! \mod ...

  2. 【BZOJ】4872: [Shoi2017]分手是祝愿 期望DP

    [题意]给定n盏灯的01状态,操作第 i 盏灯会将所有编号为 i 的约数的灯取反.每次随机操作一盏灯直至当前状态能够在k步内全灭为止(然后直接灭),求期望步数.n,k<=10^5. [算法]期望 ...

  3. BZOJ 4827 [Shoi2017]分手是祝愿 ——期望DP

    显然,考虑当前状态最少需要几步,直接贪心即可. 显然我们只需要考虑消掉这几个就好了. 然后发现,关系式找出来很简单,是$f(i) f(i+1) f(i-1)$之间的. 但是计算的时候并不好算. 所以把 ...

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

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

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

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

  6. 【BZOJ4872】【SHOI2017】分手是祝愿 期望DP

    题目大意 有\(n\)盏灯和\(n\)个开关,初始时有的灯是亮的,有的灯是暗的.按下第\(i\)个开关会使第\(j\)盏灯的状态被改变,其中\(j|i\).每次你会随机操作一个开关,直到可以通过不多于 ...

  7. BZOJ4872: [Shoi2017]分手是祝愿【概率期望DP】【思维好题】

    Description Zeit und Raum trennen dich und mich. 时空将你我分开.B 君在玩一个游戏,这个游戏由 n 个灯和 n 个开关组成,给定这 n 个灯的初始状态 ...

  8. 2018.11.01 bzoj4872: [Shoi2017]分手是祝愿(期望dp)

    传送门 一道不错的题. 考虑n==kn==kn==k的时候怎么做. 显然应该从nnn到111如果灯是开着的就把它关掉这样是最优的. 不然如果乱关的话会互相影响肯定不如这种优. 于是就可以定义状态f[i ...

  9. Bzoj4872: [Shoi2017]分手是祝愿

    题面 Bzoj Sol 首先从大向小,能关就关显然是最优 然后 设\(f[i]\)表示剩下最优要按i个开关的期望步数,倒推过来就是 \[ f[i]=f[i-1]*i*inv[n]+f[i+1]*(n- ...

随机推荐

  1. python's thirty day for me 异常处理

    ---恢复内容开始--- 程序的异常:报错之后程序终止. 异常处理搭配使用: l = ['创建老师','创建学校'] while True: try: for num,item in enumerat ...

  2. Mybatis系列(四)映射文件

    转自:https://blog.csdn.net/chris_mao/article/details/48811507 Mybatis的真正强大,在于她对SQL的映射,这也是她吸引人的地方.实现相同的 ...

  3. MySQL: [Err] 1093 - You can't specify target table 'bk' for update in FROM clause

    错误的意思说,不能先select出同一表中的某些值,再update这个表(在同一语句中). 例如下面这个sql: delete from tbl where id in (        select ...

  4. ubuntu12 安装redis和phpRedisAdmin详细流程

    一.Ubuntu安装redis(redis默认端口6379) 方式一.直接下载源码,编译(redis可以编译源码之后直接运行,不需要安装) 1.1执行命令,从官网下载源码编译: $ wget http ...

  5. [JBPM3.2]TaskNode的signal属性详解

    TaskNode节点的signal属性决定了任务完成时对流程执行继续的影响,共有六种取值:unsynchronized,never,first,first-wait,last,last-wait.默认 ...

  6. docker 制作本地镜像

    docker commit 55ddf8d62688 py_wb # 容器ID, 容器名称tag py_wb IP地址:5000/my-web:20180511 # 远程registory地址 我的镜 ...

  7. Python名称空间和闭包

    一.名称空间 1.定义:又名 name space,顾名思义,就是存放名字的地方.比如:若变量x = 1,1存放在内存中, 而名称空间正是存放名字x与1绑定关系的地方. 2.分类: locals : ...

  8. maven学习总结-eclipse开发

    一.创建Web项目 1.1 选择建立Maven Project 选择File -> New ->Project,如下图所示:

  9. c++策略模式(Strategy Method)

    别人的博客再讲策略模式时都会讲三国,策略类就是赵云的锦囊,锦囊里装着若干妙计.在打仗时想要用什么妙计,直接从锦囊里去取. 锦囊类: class context { public: context(IS ...

  10. nginx配置跨域访问

    前端要在本地测试ajax接口,无法跨域访问,所以在测试环境的nginx配置了跨域支持,方法如下: 在nginx.conf文件, http块下配置 42 #support cross domain ac ...