BZOJ4872 SHOI2017 分手是祝願

2021-08-13 17:46:55 字數 3640 閱讀 3749

題意: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

題解:

我萌先貪心好了,就不考慮隨機,找最優解。

考慮到操作第

i 個開關的時候,只會影響到≤i

的,於是我萌可以知道的是,從大到小操作一定是最優的。考慮到您操作乙個開關兩次等於不操作,所以每一次一定是找到最大的且亮著的來操作。這樣一定是最優的。複雜度為o(

nn√)

或o(n

logn

) 。

然後我們來考慮如何處理期望的問題。

首先定義f(

x)為x

步後結束的期望,顯然當x≤

k時,f(

x)=x

(因為它已經被欽定了)。

顯然有這麼個轉移

f(

x)=x

n⋅f(

x−1)

+n−x

n⋅f(

x+1)

+1

於是就得到了乙個做法。

但是我當時腦抽想到了乙個問題,mm

p 要是不能初始化f(

x)怎麼辦,就是乙個樣例(

k<

1 )……

於是就改了一種定義(其實它是可以做的見萬古神犇wys)

差分定義令g(

x)為從

x 步第一次到x−

1步的期望,於是就可以得到轉移

g(

x)=x

n⋅+n

−xn⋅

(g(x

+1)+

g(x)

+1)

其中x≤

k||x

=n時,g(

x)=1

。 這樣不用考慮初始化……

於是我們把最少步數找到,然後答案累加起來。

話說這道題完全如果給的模數不是質數,也可以做。

# include 

namespace in

inline

int read ( )

# undef pick

# undef in_len

}const

int n = 100010 ;

bool a [n] ;

int pool [n * 18], *iter = pool, cnt [n], cur [n], *d [n] ;

int main ( )

}for ( int i = 1 ; i <= n ; ++ i )

for ( int i = 1 ; i <= n ; ++ i )

for ( int j = i ; j <= n ; j += i )

for ( int i = 1 ; i <= n ; ++ i )

int rt ( 0 ) ;

for ( int i = n ; i >= 1 ; -- i )

if ( a [i] )

++ rt ;

}if ( rt <= k ) return

printf ( "%d\n", 1ll * rt * fac_n % 100003 ), 0 ;

static

int inv [n], f [n] ;

inv [1] = 1 ;

for ( int i = 2 ; i <= n ; ++ i ) inv [i] = 1ll * ( 100003 - 100003 / i ) * inv [100003 % i] % 100003 ;

for ( int i = 1 ; i <= k ; ++ i ) f [i] = 1 ;

f [n] = 1 ;

for ( int i = n - 1 ; i > k ; -- i ) f [i] = 1ll * ( 1ll * ( n - i ) * f [i + 1] % 100003 + n ) * inv [i] % 100003 ;

int ans ( 0 ) ;

for ( int i = 1 ; i <= rt ; ++ i ) ans += f [i] ;

printf ( "%d\n", 1ll * ans * fac_n % 100003 );

return

0 ;}

bzoj 4872 Shoi2017 分手是祝願

4872 shoi2017 分手是祝願 time limit 20 sec memory limit 512 mb submit 138 solved 97 submit status discuss description zeit und raum trennen dich und mich.時...

BZOJ4872 Shoi2017 分手是祝願

zeit und raum trennen dich und mich.時空將你我分開。b 君在玩乙個遊戲,這個遊戲由 n 個燈和 n 個開關組成,給定這 n 個燈的初始狀態,下標為 從 1 到 n 的正整數。每個燈有兩個狀態亮和滅,我們用 1 來表示這個燈是亮的,用 0 表示這個燈是滅的,遊戲 的...

Bzoj3562 神器化合物 Shoi 2014

ac通道 分析 若把每乙個原子看作乙個節點,將化學鍵看作一條邊,那麼這個題目要求的 分子的個數 很容易就可以看出是求圖中聯通塊的個數。求聯通塊的個數,可以使用並查集。可如何求出每一步的聯通塊的個數呢?可以知道,當連上一條邊時,若此邊連線的是兩個不同的聯通塊,那麼分子個數就會減一 當刪去一條邊時,若刪...