CF1033G Chip Game 題解
阿新 • • 發佈:2021-10-26
Link.
Description.
\(n\) 堆石子,Alice Bob 打隔膜,他們分別從 \([1,m]\) 中選一個值,設為 \(A\),\(B\)。
Alice Bob 分別可以從任意一堆中取出 \(A\)、\(B\) 個石子,不能操作的人輸。
問對於不同的 \(A,B\),以下四種狀態的方案數分別是多少。
- Alice 贏
- Bob 贏
- 先手贏
- 後手贏
\(n\le 100,m\le 10^5\)
Solution.
首先,發現 Alice 贏和 Bob 贏本質相同,方案數相同。
所以我們只需要算出先手贏、後手贏的方案數容斥就行了。
同時,顯然的性質就是狀態 \(\{v_i\}\)
證明顯然,贏的人肯定可以按照原來狀態,如果後手選了就跟他把 \(k_i\) 減一。
那我們可以考慮列舉 \(a+b\),剩下了所有的 \(v_i\le (a+b)\)。
考慮先手贏,可能會有這幾種情況
- \(\exists i\in[1,n],a\le v_i< b\),是因為先手可以苟著 \(v_i\) 最後取。
- \(\exists i\in[1,n],2a\le v_i\),有 \(2a\le v_i\le a+b\),先手可以先取一個 \(a\) 再苟。
先手能苟的情況也就只有這兩種。
考慮不能苟,那也就是說 \(\sum[v_i\ge b]\)
所以先手必敗的情況是沒有情況 1 和 2 且是偶數。
同理,後手贏的情況有以下幾種
- \(\exists i\in[1,n],b\le v_i< a\)
- \(\sum[2b\le v_i]\ge 2\)
考慮 \(\forall i\in[1,n],a\le v_i<b\) 不成立,則肯定有 \(a,b\) 在同一個 \((v_i,v_{i+1}]\) 值域區間內。
所以我們可以列舉這個值域區間,複雜度 \(O(n)\),可以 \(O(1)\) 算出 \(\sum[v_i\ge b]\)。
考慮 \(2a\le v_i\) 也不成立,所以肯定有 \(a>\frac {v_i}2\)
後手的話考慮次大就行了。
Coding.
點選檢視程式碼
//Coded by leapfrog {{{
//Coded on 2021.10.26
//是啊,你就是那隻鬼了,所以被你碰到以後,就輪到我變成鬼了
#include<bits/stdc++.h>
using namespace std;typedef long long ll;
template<typename T>inline void read(T &x)
{
x=0;char c=getchar(),f=0;
for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
f?x=-x:x;
}
template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}//}}}
int n,m,b[105];ll a[105],rfs,rsc;
int main()
{
read(n,m);for(int i=1;i<=n;i++) read(a[i]);
for(int S=2;S<=m+m;S++)
{
for(int i=1;i<=n;i++) b[i]=a[i]%S;
b[n+1]=0,b[n+2]=S-1,sort(b+1,b+n+3);
for(int i=n+2;i>1;i--)
{
int fg=(n+2-i)&1,l=max(b[i-1],b[n+!fg]/2)+1,r=min(b[i],m);
(fg?rfs:rsc)+=max(min(r,S-l)-max(l,S-r)+1,0);
}
}
ll rs=(1ll*m*m-rfs-rsc)>>1;
return printf("%lld %lld %lld %lld\n",rs,rs,rfs,rsc),0;
}