[CF1523E]Crypto Lights

Posted Tan_tan_tann

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CF1523E]Crypto Lights相关的知识,希望对你有一定的参考价值。

Crypto Lights

题目大意

给你一个长度为 n n n 0 / 1 0/1 0/1序列,最开始全都为 0 0 0。你将一直执行下列操作:

  • 从为 0 0 0的点中等概率选择一个点,将其变为 1 1 1
  • 如果有两个为 1 1 1的点之间距离小于 k k k,则停止操作,否则继续执行上面的操作。

请问你执行停止后序列中 1 1 1的期望个数。 ( 2 ⩽ k ⩽ n ⩽ 1 0 5 ) (2\\leqslant k\\leqslant n\\leqslant 10^5) (2kn105)

题解

先吐槽一下这题意真的很难懂,我读错了 3 3 3次。

image-20210531210709569

法一

我们可以发现 E ( N u m b e r   o f   1 ′ s   o c c u r r e n c e s ) = E ( t i m e s   w h i l e   s t o p ) = E ( t i m e s   b e f o r e   s t o p ) + 1 E(Number\\,of\\,1's\\,occurrences)=E(times\\,while\\,stop)=E(times\\, before\\,stop)+1 E(Numberof1soccurrences)=E(timeswhilestop)=E(timesbeforestop)+1
我们可以去寻找在停止之前操作了多少次。

假设我们已经操作了 p p p次,那么我们现在有 p p p 1 1 1,而每两个 1 1 1之间至少有 k − 1 k-1 k1 0 0 0,总共有 ( p − 1 ) ( k − 1 ) (p-1)(k-1) (p1)(k1) 0 0 0
我们将这 ( p − 1 ) ( k − 1 ) (p-1)(k-1) (p1)(k1) 0 0 0去掉,我们之后相当于从剩 n − ( p − 1 ) ( k − 1 ) n-(p-1)(k-1) n(p1)(k1)个位置中选择 k k k个为 1 1 1,再将那 ( p − 1 ) ( k − 1 ) (p-1)(k-1) (p1)(k1) 0 0 0插入两个不同位置的 1 1 1中间的空隙中。可以发现,这样与合法的方案是一一对应的。
于是,我们选择 p p p个数时未停止的方案数为 ( n − ( p − 1 ) ( k − 1 ) p ) p ! \\binom{n-(p-1)(k-1)}{p}p! (pn(p1)(k1))p!,而每种方案的概率为 ( n − i ) ! n ! \\frac{(n-i)!}{n!} n!(ni)!

所以我们的期望的操作次数为 ∑ i = 1 n ( n − ( i − 1 ) ( k − 1 ) i ) i ! ( n − i ) ! n ! \\sum_{i=1}^{n}\\frac{\\binom{n-(i-1)(k-1)}{i}i!(n-i)!}{n!} i=1nn!(in(i1)(k1))i!(ni)!
加上 1 1 1就是最后的答案。

法二

或者我们可以直接考虑在什么时候停止,还是可以用上面的方法退出选择 i i i个数时未停止的方案数为 ( n − ( i − 1 ) ( k − 1 ) i ) i ! \\binom{n-(i-1)(k-1)}{i}i! (in(i1)(k1))i!,记作 g i g_{i} gi
那么选择 i i i个时已停止的方案数为 ( n − i + 1 ) d p i − 1 − d p i (n-i+1)dp_{i-1}-dp_{i} (ni+1)dpi1dpi
答案为 ∑ i = 1 n ( ( n − i + 1 ) d p i − 1 − d p i ) ( n − i ) ! n ! \\sum_{i=1}^{n}((n-i+1)dp_{i-1}-dp_{i})\\frac{(n-i)!}{n!} i=1n((ni+1)dpi1dpi)n!(ni)!

其实两种做法本质上是一样的。

时间复杂度都是 O ( n ) O\\left(n\\right) O(n)

源码

法一

#include<bits/stdc++.h>
using namespace std;
#define MAXN 200005
#define lowbit(x) (x&-x)
#define reg register
#define mkpr make_pair
#define fir first
#define sec second
typedef long long LL;
typedef unsigned long long uLL;
const LL INF=0x3f3f3f3f3f3f3f3f;
const int mo=1e9+7;
const int zero=500;
const LL jzm=2333;
const int orG=3,invG=332748118;
const double Pi=acos(-1.0);
typedef pair<int,int> pii;
const double PI=acos(-1.0);
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){
	_T f=1;x=0;char s=getchar();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
	x*=f;
}
template<typename _T>
void print(_T x){if(x<0){x=(~x)+1;putchar('-');}if(x>9)print(x/10);putchar(x%10+'0');}
int add(int x,int y){return x+y<mo?x+y:x+y-mo;}
int t,n,k,pow2[MAXN],fac[MAXN],f[MAXN],inv[MAXN],ans;
int qkpow(int a,int s){int t=1;while(s){if(s&1)t=1ll*a*t%mo;a=1ll*a*a%mo;s>>=1;}return t;}
void init(){
	pow2[0]=1;for(int i=1;i<=1e5;i++)pow2[i]=2ll*pow2[i-1]%mo;
	fac[0]=fac[1]=f[1]=inv[0]=inv[1]=1;
	for(int i=2;i<=1e5;i++)
		fac[i]=1ll*i*fac[i-1]%mo,
		f[i]=1ll*以上是关于[CF1523E]Crypto Lights的主要内容,如果未能解决你的问题,请参考以下文章

1523 E - Crypto Lights(期望+组合数学思维)

CF294C Shaass and Lights

BUUCTF CRYPTO部分题目wp

POJ 1222 EXTENDED LIGHTS OUT

hdu3404 Switch lights

poj1222 EXTENDED LIGHTS OUT