[2018雅禮集訓1-2]取石子 分類討論+組合數學
阿新 • • 發佈:2019-01-23
題面
首先所有石子先對
然後每堆石子數有以下幾種情況。
1.
2.
3.
4.
先把這四種情況個數統計出來。具體必勝情況如下:
Alice勝:
1.
2.
3.
Bob勝:不存在
先手勝:在 nt2=0
1.
2.
後手勝:在
組合計數一下就好,根據組合數性質,
所以要特判
程式碼:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=100010;
const int mod=1000000007;
int n,x[maxn],a,b,cnt[4];
ll ans[4],mi[maxn];
int main()
{
scanf("%d%d%d",&n,&a,&b);
mi[0]=1;
for(int i=1;i<=n;i++)
mi[i]=(mi[i-1]<<1)%mod;
bool lab=(a>b);
if(lab) swap(a,b);
for(int i=1;i<=n;i++)
scanf("%d ",&x[i]);
for(int i=1;i<=n;i++)
{
x[i]%=(a+b);
if(a<=x[i]&&x[i]<b) cnt[0]++;
else if(b<=x[i]&&x[i]<2*a) cnt[1]++;
else if(2*a<=x[i]) cnt[2]++;
else cnt[3]++;
}
ans[0]=(mi[n]-mi[n-cnt[0]]+mi[cnt[1]+cnt[3]]*(mi[cnt[2]]-cnt[2]-1)%mod+mod)%mod;
ans[2]=mi[cnt[3]+max(cnt[1]-1,0)]*cnt[2]%mod;
if(cnt[1]) (ans[0]+=mi[cnt[3]+cnt[1]-1]*cnt[2]%mod)%=mod,(ans[2]+=mi[cnt[3]+cnt[1]-1])%=mod;
ans[3]=mi[cnt[3]+max(cnt[1]-1,0)]%mod;
swap(ans[0],ans[lab]);
for(int i=0;i<=3;i++)
printf("%lld ",ans[i]);
return 0;
}