直接说做法了,挺好理解的。
钦定 a ≤ b a\le b a≤b。
设 r = x m o d ( a + b ) r=x\mod (a+b) r=xmod(a+b)。
分四种情况讨论:
可能 b b b和 2 a 2a 2a的大小关系会有问题,但是没有太大关系。(按照代码中的那样分类就是了)
答案先乘上 2 c n t 1 2^{cnt1} 2cnt1。
计算先手必胜和后手必胜的方案:
先手必胜: ∑ i m o d 2 = 1 ( c n t 3 i ) + ∑ i m o d 2 = 0 ( c n t 3 i ) c n t 4 \sum_{i\mod 2=1} \binom{cnt3}{i}+\sum_{i\mod 2=0}\binom{cnt3}{i}cnt4 ∑imod2=1(icnt3)+∑imod2=0(icnt3)cnt4
后手必胜: ∑ i m o d 2 = 0 ( c n t 3 i ) \sum_{i\mod 2=0} \binom{cnt3}{i} ∑imod2=0(icnt3)(这里没有 c n t 4 cnt4 cnt4的原因是如果有 A A A必胜)
using namespace std;
#include
#include
#include
#define N 100010
#define mo 1000000007
#define ll long long
ll qpow(ll x,ll y=mo-2){
ll r=1;
for (;y;y>>=1,x=x*x%mo)
if (y&1)
r=r*x%mo;
return r;
}
ll fac[N],ifac[N];
ll C(int m,int n){
return fac[m]*ifac[n]%mo*ifac[m-n]%mo;}
void initC(int n){
fac[0]=1;
for (int i=1;i<=n;++i)
fac[i]=fac[i-1]*i%mo;
ifac[n]=qpow(fac[n]);
for (int i=n-1;i>=0;--i)
ifac[i]=ifac[i+1]*(i+1)%mo;
}
int n,a,b;
int x[N];
ll ansA,ansB,ansF,ansS;
void work(){
initC(n);
ll cnt1=0,cnt2=0,cnt3=0,cnt4=0;
for (int i=1;i<=n;++i){
int r=x[i]%(a+b);
if (r<a)
cnt1++;
else if (r<b)
cnt2++;
else if (r<a*2)
cnt3++;
else
cnt4++;
}
for (int i=0;i<=cnt3;++i)
if (i&1)
(ansF+=C(cnt3,i))%=mo;
else{
(ansS+=C(cnt3,i))%=mo;
(ansF+=C(cnt3,i)*cnt4)%=mo;
}
ll tmp=qpow(2,cnt1);
(ansF*=tmp)%=mo;
(ansS*=tmp)%=mo;
ansA=(qpow(2,n)-ansF-ansS+mo+mo)%mo;
}
int main(){
// freopen("in.txt","r",stdin);
freopen("stone.in","r",stdin);
freopen("stone.out","w",stdout);
scanf("%d%d%d",&n,&a,&b);
for (int i=1;i<=n;++i)
scanf("%d",&x[i]);
if (a>b){
swap(a,b);
work();
swap(ansA,ansB);
}
else
work();
printf("%lld %lld %lld %lld\n",ansA,ansB,ansF,ansS);
return 0;
}