#include #include #include #include #define REP(i,a,b) for(i=a;i0){ q=r0/r1; r2=r0%r1; a2=a0-q*a1; b2=b0-q*b1; r0=r1; r1=r2; a0=a1; a1=a2; b0=b1; b1=b2; } *c=r0; *a=a0; *b=b0; } ll get_inv(ll n, ll p){ ll a,b,c; extended_euclid(n,p,&c,&a,&b); if(ak);if(i>=j)break;t=d[i];d[i]=d[j];d[j]=t;t=m[i];m[i]=m[j];m[j]=t;}intIntSort(d,m,i);intIntSort(d+j+1,m+j+1,s-j-1);} int count[100000], S[100000], res[100000], ind[100000]; int event[100001], tm[100001], eve_size; ll fact[100001]; ll inv[100001]; int main(){ int i,j,k; int N, Q, sum, sumh; ll now, nowh; int odd; REP(i,1,100001) inv[i] = get_inv(i, M); fact[0] = 1; REP(i,1,100001) fact[i] = (fact[i-1] * i)%M; assert( scanf("%d",&N)==1 ); assert(1 <= N && N <= 100000); rep(i,N) assert( scanf("%d",count+i)==1 ), assert(1<=count[i] && count[i]<=100000); assert( scanf("%d",&Q)==1 ); assert(1<=Q && Q<=100000); rep(i,Q) assert( scanf("%d",S+i)==1 ), ind[i] = i, assert(1 <= S[i] && S[i] <= 1000000000); intIntSort(S,ind,Q); /* sort queries */ /* sum = sum of count[i] */ /* sumh = sum of floor(count[i]/2) */ /* odd = number of the odd elements in count */ sum = 0; rep(i,N) sum += count[i]; assert(1 <= sum && sum <= 100000); sumh = 0; rep(i,N) sumh += count[i]/2; odd = 0; rep(i,N) odd += count[i]%2; /* now = number of the all permutations */ /* nowh = number of the symmetric permutations */ /* (the answer will be (now + nowh)/2 mod M)*/ now = 1; rep(i,N) now = (now * fact[count[i]])%M; now = get_inv(now, M); now = (now * fact[sum])%M; nowh = 1; rep(i,N) nowh = (nowh * fact[count[i]/2]) % M; nowh = get_inv(nowh, M); nowh = (nowh * fact[sumh]) % M; /* Store all events (like the below) and sort it */ /* When S goes from k-1 to k, the number of box corresponding count[i] will go from j+1 to j. */ eve_size = 0; rep(i,N){ for(j=count[i]-1;j>=1;j--){ k = (count[i]+j-1)/j; event[eve_size] = i; tm[eve_size++] = k; } } intIntSort(tm,event,eve_size); /* Simulate that S goes from 1 to infinity, and calculate the answer */ k = 0; rep(i,Q){ while(k < eve_size && tm[k] <= S[i]){ now = (now * inv[sum]) % M; now = (now * count[event[k]]) % M; sum--; if(count[event[k]]%2==0){ nowh = (nowh * inv[sumh]) % M; nowh = (nowh * (count[event[k]]/2)) % M; odd++; sumh--; } else { odd--; } count[event[k]]--; k++; } if(odd <= 1) res[ind[i]] = ((now + nowh) * inv[2]) % M; else res[ind[i]] = (now * inv[2]) % M; } rep(i,Q) printf("%d\n",res[i]); return 0; }