題目傳送門
題目大意:乙個長度為 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...