Luogu5400 CTS2019 random cube (inclusion and exclusion)

  Consider the inclusion-exclusion, calculated probability that at least a great number of k. This may assume that k is the number corresponding to the grid sequentially (k, k, k) ...... (1,1,1). So a dimensional coordinates <= k plaid plaid whether these would be a very great number of impact. First of all such correspondence grid and set up a number, the answer is about to take on a number of combinations. You then need to consider is how many of these lattice legitimate the order.

  This arrangement is needed to satisfy (i, i, i) can not occur until a i-dimensional coordinates of a grid. It can be seen as filled out (i, i, i), the minimum value of all three-dimensional coordinate grid of i can be filled. Such a grid is easy to calculate the number. So consider successively into a lattice arrangement, the first one obviously only put (k, k, k), then all the three-dimensional coordinates of the minimum value of k is unlocked grid, in combination with a number of them arranged in an arbitrary position, continue discharge (k-1, k-1, k-1), and so on.

  The last of such a technology to get something, to be calculated can be found in an array of inverse product prefix. You can use the classic trick, to obtain the entire array and then plot the inverse reverse reduction, to achieve linear.

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define P 998244353
#define N 5000010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
    int x=0,f=1;char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
int T,n,m,l,k,fac[N],inv[N],f[N],g[N];
int ksm(int a,int k)
{
    int s=1;
    for (;k;k>>=1,a=1ll*a*a%P) if (k&1) s=1ll*s*a%P;
    return s;
}
int Inv(int a){return ksm(a,P-2);}
void inc(int &x,int y){x+=y;if (x>=P) x-=P;}
int C(int n,int m){if (m>n) return 0;return 1ll*fac[n]*inv[m]%P*inv[n-m]%P;}
int A(int n,int m){if (m>n) return 0;return 1ll*fac[n]*inv[n-m]%P;}
int min(int x,int y,int z){return min(min(x,y),z);}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    const char LL[]="%I64d\n";
#else
    const char LL[]="%lld\n";
#endif
    T=read();
    fac[0]=1;for (int i=1;i<=N-10;i++) fac[i]=1ll*fac[i-1]*i%P;
    inv[0]=inv[1]=1;for (int i=2;i<=N-10;i++) inv[i]=P-1ll*(P/i)*inv[P%i]%P;
    for (int i=2;i<=N-10;i++) inv[i]=1ll*inv[i]*inv[i-1]%P;
    while (T--)
    {
        n=read(),m=read(),l=read(),k=read();
        int ans=0;
        for (int i=1;i<=min(n,m,l);i++) f[i]=(1ll*(n-i+1)*(m-i+1)%P*(l-i+1)%P-1ll*(n-i)*(m-i)%P*(l-i)%P+P)%P;
        for (int i=1;i<=min(n,m,l);i++) f[i]=(f[i]+f[i-1])%P;g[min(n,m,l)]=1;
        for (int i=1;i<=min(n,m,l);i++) g[min(n,m,l)]=1ll*g[min(n,m,l)]*f[i]%P;
        g[min(n,m,l)]=Inv(g[min(n,m,l)]);
        for (int i=min(n,m,l)-1;i>=1;i--) g[i]=1ll*g[i+1]*f[i+1]%P;
        for (int i=k;i<=min(n,m,l);i++)
        {
            int waytochoosemax=1ll*A(n,i)*A(m,i)%P*A(l,i)%P;
            if (i-k&1) inc(ans,P-1ll*C(i,k)*waytochoosemax%P*g[i]%P);
            else inc(ans,1ll*C(i,k)*waytochoosemax%P*g[i]%P);
        }
        cout<<ans<<endl;
    }
    return 0;
}

  

Guess you like

Origin www.cnblogs.com/Gloid/p/10936699.html