#include #define ff first #define ss second #define ll long long #define pb push_back using namespace std; typedef pair pii; const int maxn=40; const int mod=1e9+7; inline int add(int x,int y){int ret=x+y;if(ret>=mod)ret-=mod;return ret;} inline int sub(int x,int y){int ret=x-y;if(ret<0)ret+=mod;return ret;} inline int mul(int x,int y){return ((ll)x*y)%mod;} inline int step(int base,int pw){int ret=1;while(pw){if(pw&1)ret=mul(ret,base);base=mul(base,base);pw>>=1;}return ret;} inline int invv(int x){return step(x,mod-2);} struct mvect{ int n; vectora; mvect(int n){ a.resize(n); this->n=n; } mvect operator *(mvect &b){ mvect ret(n); for(int j=0;j=n)id-=n; ret.a[id]=add(ret.a[id],mul(b.a[j],a[k])); } return ret; } mvect operator +(mvect &b){ mvect ret(n); for(int k=0;k>=1; } return ret; } void finish_off(vector >&vect){ mvect ret(d); for(int i=0;i > sol2_getcoef(){ vector >dp[2]; int curr=0; for(int i=0;i<2;i++){ dp[i].resize(S+1); for(int j=0;j<=S;j++){ dp[i][j].resize(S+1); } } dp[0][0][0]=1; for(int i=1;i<=n;i++){ curr^=1; for(int j=0;j<=S;j++) for(int k=0;k<=S;k++){ dp[curr][j][k]=0; if(j-x[i]>=0)dp[curr][j][k]=add(dp[curr][j][k],dp[curr^1][j-x[i]][k]); if(k-x[i]>=0)dp[curr][j][k]=add(dp[curr][j][k],dp[curr^1][j][k-x[i]]); } } vector >ret; int invS=invv(S); int invd=invv(step(d,n)); for(int i=0;i<=S;i++){ for(int j=0;j<=S;j++){ ///printf("%d %d | %d DP\n",i,j,dp[curr][i][j]); dp[curr][i][j]=mul(dp[curr][i][j],invd); mvect pom(d); pom.a[0]=mul(i,invS); pom.a[1]=mul(j,invS); ret.pb({dp[curr][i][j],pom}); } } return ret; } void sol2(){ vector >pom=sol2_getcoef(); finish_off(pom); } vector > sol3_getcoef(){ vector >dp[2]; int curr=0; for(int i=0;i<2;i++){ dp[i].resize(S+1); for(int j=0;j<=S;j++){ dp[i][j].resize(S+1); } } dp[0][0][0]=1; int xsum=0; for(int i=1;i<=n;i++){ curr^=1; xsum+=x[i]; for(int j=0;j<=S;j++) for(int k=0;k<=S;k++){ dp[curr][j][k]=0; if(j-x[i]>=0)dp[curr][j][k]=add(dp[curr][j][k],dp[curr^1][j-x[i]][k]); if(k-x[i]>=0)dp[curr][j][k]=add(dp[curr][j][k],dp[curr^1][j][k-x[i]]); int treci=xsum-j-k; if(treci-x[i]>=0)dp[curr][j][k]=add(dp[curr][j][k],dp[curr^1][j][k]); } } vector >ret; int invS=invv(S); int invd=invv(step(d,n)); for(int i=0;i<=S;i++){ for(int j=0;j<=S;j++){ if(dp[curr][i][j]==0)continue; ///printf("%d %d | %d DP\n",i,j,dp[curr][i][j]); dp[curr][i][j]=mul(dp[curr][i][j],invd); mvect pom(d); pom.a[0]=mul(i,invS); pom.a[1]=mul(j,invS); pom.a[2]=mul(S-i-j,invS); ret.pb({dp[curr][i][j],pom}); } } return ret; } void sol3(){ vector >pom=sol3_getcoef(); finish_off(pom); } vector > sol4_getcoef(){ vector >dp[2]; int curr=0; for(int i=0;i<2;i++){ dp[i].resize(2*S+1); for(int j=0;j<=S*2;j++){ dp[i][j].resize(2*S+1); } } dp[0][S][S]=1; int xsum=0; for(int i=1;i<=n;i++){ ///printf("\n%d IIIIIIIIIIIII\n",i); curr^=1; xsum+=x[i]; for(int j=0;j<=S*2;j++) for(int k=0;k<=S*2;k++){ dp[curr][j][k]=0; if(j-x[i]>=0)dp[curr][j][k]=add(dp[curr][j][k],dp[curr^1][j-x[i]][k]); if(j+x[i]<=2*S)dp[curr][j][k]=add(dp[curr][j][k],dp[curr^1][j+x[i]][k]); if(k-x[i]>=0)dp[curr][j][k]=add(dp[curr][j][k],dp[curr^1][j][k-x[i]]); if(k+x[i]<=2*S)dp[curr][j][k]=add(dp[curr][j][k],dp[curr^1][j][k+x[i]]); ///printf("%d %d | %d DP\n\n",j-S,k-S,dp[curr][j][k]); } } vector >ret; int invS=invv(S); int invd=invv(step(d,n)); for(int i=0;i<=S*2;i++){ for(int j=0;j<=S*2;j++){ if(dp[curr][i][j]==0)continue; ///printf("%d %d | %d DP\n",i-S,j-S,dp[curr][i][j]); dp[curr][i][j]=mul(dp[curr][i][j],invd); mvect pom(d); int p1=i-S; if(p1<0)p1+=mod; int p2=j-S; if(p2<0)p2+=mod; pom.a[0]=mul(p1,invS); pom.a[1]=mul(p2,invS); pom.a[2]=0; pom.a[3]=0; ret.pb({dp[curr][i][j],pom}); } } return ret; } void sol4(){ vector >pom=sol4_getcoef(); finish_off(pom); } int main(){ freopen("medals.in","r",stdin); freopen("medals.out","w",stdout); ///scanf("%d %d %d",&n,&b,&d); cin>>n>>b>>d; for(int i=1;i<=n;i++){ ///scanf("%d",&x[i]); cin>>x[i]; S+=x[i]; } if(d==1)sol1(); else if(d==2)sol2(); else if(d==3)sol3(); else if(d==4)sol4(); return 0; }