UNR # 3 one hundred Colombard

Subject to the effect: in UOJ Administrators group in a total of \ (N \) an administrator, in order to accommodate these administrators, vfk prepared \ (N + 1 \) a pigeon holes.

To save space, these pigeon holes VFK piled up, a total of \ (n-\) column, column i put \ (a_i \) a pigeonhole, satisfy \ (\ N = a_i + SUM. 1 \) .

Whenever the end of the UR, administrators will be ascending order according to the number back to pigeon holes, each administrator came back, will first equal probability of a random row in all there is a surplus of Colombard column and then live the rest of this column in the pigeon holes in a minimal number.

Now \ (N \) after a return of the administrators, there is a will empty out a pigeon holes. For each column you can obtain the probability of this column empty pigeon holes do?

\ (A_i \ 30, N \ 30 \)

With PKUWC2018 hunters kill like.

Unnecessary step, the problem can be transformed into an infinite selected until only a \ (a_i> 0 \)

For each point, enumerate a collection \ (S \) , calculated this point in the set \ (S \) probability of being deleted before completion of all the points. Clearly set of operations outside of us can ignore. Operation of the internal collection we can be ignored.

Consider this sequence of operations selected point is, when finished, and this thing can be made out of a backpack. Thus there is a \ (2 ^ n * somthing \ ) thing complexity. We add one-dimensional representation of the current size of the collection, on the line.

Xia Xie out of, the complexity found reached \ (O (n-4M ^ 2 ^) \) , the T. We finished the backpack and then revoked on the line.

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=998244353;
inline int add(int a,int b){a+=b;return a>=mod?a-mod:a;}
inline int sub(int a,int b){a-=b;return a<0?a+mod:a;}
inline int mul(int a,int b){return (ll)a*b%mod;}
inline int qpow(int a,int b){int ret=1;for(;b;b>>=1,a=mul(a,a))if(b&1)ret=mul(ret,a);return ret;}
inline int inv(int x){return qpow(x,mod-2);}
/* math */
const int N = 40, SZ = 910;
int n,a[N];
int binom[2010][2010];
inline void preset(int n=2000){
    binom[0][0]=1;
    for(int i=1;i<=n;i++){
        binom[i][0]=binom[i][i]=1;
        for(int j=1;j<i;j++)binom[i][j]=add(binom[i-1][j-1],binom[i-1][j]);
    }
}
int f[N][SZ];
int g[N][SZ];

int sum = 0;
inline void package(int sz){
    for(int i=1;i<=n;i++){
        for(int j=0;j<=sum;++j){
            g[i][j]=f[i][j];
            for(int d=0;d<sz&&j-d>=0;d++){
                g[i][j]=add(g[i][j],mul(f[i-1][j-d],binom[j][d]));
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=0;j<=sum;++j){
            f[i][j]=g[i][j];
        }
    }
}

inline void unpackage(int sz){
    for(int i=1;i<=n;i++){
        for(int j=0;j<=sum;++j){
            g[i][j]=f[i][j];
            for(int d=0;d<sz&&j-d>=0;d++){
                g[i][j]=sub(g[i][j],mul(f[i-1][j-d],binom[j][d]));
            }
            f[i][j]=g[i][j];
        }
    }
}


int main()
{
    preset();
    cin >> n;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),sum+=a[i];
    f[0][0]=1;
    for(int i=1;i<=n;i++)package(a[i]);
    for(int i=1;i<=n;i++){
        unpackage(a[i]);
        int ans=0;
        for(int S=1;S<=n;++S){
            for(int len=0;len<=sum;++len){
                int totlen = len+a[i], way = mul(f[S-1][len], binom[len+a[i]-1][a[i]-1]);
                int p=qpow(inv(S),totlen);
                if(S&1) ans=add(ans, mul(p,way));
                else ans=sub(ans, mul(p,way));
            }
        }
        package(a[i]);
        printf("%d ",ans);
    }
    puts("");
}

Guess you like

Origin www.cnblogs.com/weiyanpeng/p/11116186.html