SDOI 2019 移動金幣 題解

2021-10-24 13:44:23 字數 2161 閱讀 2708

題目傳送門

題目大意:乙個長度為 n

nn 的序列上有 m

mm 個金幣,兩個人輪流操作,乙個人可以將乙個金幣向左移動任意格,但是不能越過別的金幣,問有多少種局面先手必勝。

感覺像這兩題(1,2)的合體,不過合的也很巧妙。

轉化一下這個博弈:相當於有 m+1

m+1m+

1 堆石子,每次可以將一堆石子中的若干個移到下一堆內,第 m+1

m+1m+

1 堆的不可以被操作。

對於第 i

ii 堆石子,假如 m+1

−i

m+1-i

m+1−

i 為偶數,那麼這堆石子其實是沒用的,假如 alice

\text

alice

將其中若干個移到下一堆,那麼 bob

\text

bob 接著將這若干個再移到下一堆,那麼這若干個依然在 m+1

−i

m+1-i

m+1−

i 為偶數的堆內,一直搞下去那麼這些石子最後就會停在第 m+1

m+1m+

1 堆內,此時依然是 alice

\text

alice

操作。那麼如果將 m+1

−i

m+1-i

m+1−

i 為奇數的堆內的石子移到下一堆,那麼這些石子就變成了沒用的石子了,則 m+1

−i

m+1-i

m+1−

i 為奇數的堆就構成了乙個 nim

nimni

m 遊戲,於是 dp

\text

dp 一下就做完了,dp

\text

dp 部分和上面鏈結裡第二題是一樣的,做過的話就不用再看我講一次了。

現在的子問題是 n

nn 個石子分成 m

mm 堆構成的 nim

nimni

m 遊戲有多少種情況先手必勝(注意這裡 n,m

n,mn,

m 和上面的不是同乙個),這不太好求,正難則反,考慮必敗的情況數,令 f[i

]f[i]

f[i]

表示 i

ii 個石子分 m

mm 堆先手必敗的方案數。先手必敗需要滿足:將每堆石子數量轉成二進位制數後,對於任意 j

jj,第 j

jj 位為 1

11 的數的個數為偶數。考慮列舉每一位 1

11 的個數,用組合數將他們分配到 m

mm 堆內,就可以做 dpdp

dp了,時間複雜度 o(17

nm

)o(17nm)

o(17nm

)。**如下:

#include

#include

#include

using

namespace std;

#define maxn 150010

#define mod 1000000009

int n,m,k;

int binom[maxn][61

];void

add(

int&x,

int y)

intadd

(int x)

void

binominit()

}}int f[maxn]

,tmp[maxn]

;int

main()

}for

(int j=

0;j<=n-m;j++

)f[j]

=tmp[j]

,tmp[j]=0

;}int ans=0;

for(

int i=

0;i<=n-m;i++

)add

(ans,

1ll*f[i]

*binom[n-m-i+

(m+1

-k-1)]

[m+1

-k-1

]%mod)

; ans=

(binom[n-m+

(m+1-1

)][m+1-1

]-ans+mod)

%mod;

printf

("%d"

,ans)

;}

移動金幣 SDOI2019

乙個 1 times n 的棋盤上最初擺放有 m 枚金幣。其中每一枚金幣佔據了乙個獨立的格仔,任意乙個格仔內最多只有一枚金幣。alice 和 bob 將要進行如下的一場遊戲。二人輪流操作,且 alice 先行。當輪到乙個玩家的時候,他可以選擇一枚金幣,並將其向左移動任意多格,且至少移動一格。金幣不能...

SDOI2019移動金幣 博弈論

題意簡述 在乙個 1 n 的棋盤上,有 m 個棋子.小 a 小 b 每次可以把乙個棋子向左移動若干格,但不能越過其他棋子.第乙個無法操作的人輸.問給定 n,m 有多少種局面使得 小a 必勝 n leq 150000,m leq 50 sdoi2019 移動金幣 includeusing namesp...

SDOI 2019 快速查詢

傳送門 day1 t1 給定乙個長度為 n nn 的整數數列 有 q qq 次操作,操作有 6 66 種,分別為 單點賦值,全域性加,全域性乘,全域性賦值,單點查值,全域性求和。操作的讀入有點鬼畜啊,建議仔細讀一下。資料範圍 1 n 109 1 n 10 9 1 n 10 9,1 q 10 71 l...