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

【算法】期望DP

【题解】对于当前状态,编号最大的亮灯必须通过操作自身灭掉

证明:假设通过操作编号更大的灯灭掉,那么编号更大的灯只能通过操作自己灭掉,则与原来状态无区别,得证。

运用这个结论,每次灭掉最大编号的灯后的局面中,编号最大的灯一定严格小于原最大灯,所以至多需要n次操作。

从大到小,处理出m盏待操作灯,这样一个局面就可以描述成待操作灯的数目,从而考虑期望DP。

最直观地,设f[i]表示剩余 i 盏操作灯的期望步数,根据全期望公式:

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

等等,高斯消元?不资瓷!我们想办法变成单方向DP,去掉f[i-1]。

设f[i]表示从 i 盏待操作灯变成 i-1 盏待操作灯的期望步数,那么根据全期望公式:(省略i/n*0)

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

好啦!移项即可计算f[i],最后:

$$ans=\sum_{i=k+1}^{m}f[i]*n!$$

复杂度O(n√n)。

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=,MOD=;
int n,m,k,ans,a[maxn],f[maxn];
void exgcd(int a,int b,int &x,int &y){if(!b){x=;y=;}else{exgcd(b,a%b,y,x);y-=x*(a/b);}}
int inv(int a){int x,y;exgcd(a,MOD,x,y);return (x%MOD+MOD)%MOD;}
int main(){
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++)scanf("%d",&a[i]);
for(int i=n;i>=;i--)if(a[i]){
m++;
for(int j=;j*j<=i;j++)if(i%j==){
if(j*j==i)a[j]^=;else a[j]^=,a[i/j]^=;
}
}
for(int i=n;i>k;i--)f[i]=(n+1ll*(n-i)*f[i+]%MOD)*inv(i)%MOD;
if(m<=k)ans=m;else{
for(int i=m;i>k;i--)ans=(ans+f[i])%MOD;
ans=(ans+k)%MOD;
}
for(int i=;i<=n;i++)ans=1ll*ans*i%MOD;
printf("%d",ans);
return ;
}

【BZOJ】4872: [Shoi2017]分手是祝愿 期望DP的更多相关文章

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

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

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

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

  3. bzoj 4872: [Shoi2017]分手是祝愿

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

  4. 【bzoj4872】[Shoi2017]分手是祝愿 期望dp

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. C#高级编程 (第六版) 学习 第三章:对象和类型

    第三章 对象和类型 1,类和结构 类存储在托管堆上 结构存储在堆栈上   2,类成员 类中的数据和函数称为类成员 数据成员 数据成员包括了字段.常量和事件   函数成员 方法:与某个类相关的函数,可以 ...

  2. mac python install zlib not available

    用brew install 3.4.4(python)时报 zipimport.ZipImportError: can't decompress data; zlib not available 的错 ...

  3. 【UNIX环境编程、操作系统】孤儿进程和僵尸进程

    基本概念: 在类UNIX系统中,僵尸进程是指完成执行(通过exit系统调用,或运行时发生致命错误或收到终止信号所致)但在操作系统的进程表中仍然有一个进程表表项(进程控制块PCB),处于"终止 ...

  4. c++字符串排序

    在主函数中输入10个等长的字符串,用另一函数对它们排序.然后在主函数输出这10个已排好序的字符串. 用两种方法完成. 方法一:用二维数组做函数参数: 方法二:用指向一维数组的指针做函数参数. 方法一: ...

  5. 洛谷 P4390 [BOI2007]Mokia 摩基亚 解题报告

    P4390 [BOI2007]Mokia 摩基亚 题目描述 摩尔瓦多的移动电话公司摩基亚(\(Mokia\))设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如"用户 ...

  6. hadoop(三)HDFS基础使用

    一.HDFS前言 1. 设计思想          分而治之:将大文件,大批量文件,分布式的存放于大量服务器上.以便于采取分而治之的方式对海量数据进行运算分析     2. 在大数据系统架构中的应用  ...

  7. bzoj3192: [JLOI2013]删除物品(树状数组)

    既然要从一个堆的堆顶按顺序拿出来放到第二个堆的堆顶,那么我们就可以把两个堆顶怼在一起,这样从一个堆拿到另一个堆只需要移动指针就好了. 换句话说,把1~n倒着,n+1到n+m正着,用一个指针把两个序列分 ...

  8. 2656: [Zjoi2012]数列(sequence)(递归+高精度)

    好久没写题了T T NOIP 期中考双血崩 显然f(x)=f(x>>1)+f((x>>1)+1),考虑每次往x>>1递归,求出f(x),复杂度O(logN) 我们设 ...

  9. mysql数据库----python操作mysql ------pymysql和SQLAchemy

    本篇对于Python操作MySQL主要使用两种方式: 原生模块 pymsql ORM框架 SQLAchemy 一.pymysql pymsql是Python中操作MySQL的模块,其使用方法和MySQ ...

  10. 在 Ubuntu16.04上安装anaconda+Spyder+TensorFlow(支持GPU)

    TensorFlow 官方文档中文版 http://www.tensorfly.cn/tfdoc/get_started/introduction.html https://zhyack.github ...