zoukankan      html  css  js  c++  java
  • CTSC2019

    (upd:随机立方体AC)

    太菜了只会部分分。以后慢慢补坑吧……

    随机立方体:

    30分:

    正常人都能想到的的转移状态(我的确是弱智),从大往小填数,记录有多少个极大值点和三个方向上各占了多少。转移可以计算。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    #define upd(x,y) x+=y,x%=P
    
    typedef long long i64;
    
    const int N=13;
    const int P=998244353;
    
    int f[2][N][N][N][N];
    
    int pwr(int x,int a){
        int s=1;
        while(a){
            if(a&1)s=(i64)s*x%P;
            x=(i64)x*x%P;
            a>>=1;
        }
        return s;
    }
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--){
            int r,c,l,n,m;
            scanf("%d%d%d%d",&r,&c,&l,&m);
            n=r*c*l;
            if(m>r&&m>c&&m>l){
                printf("0
    ");
                continue;
            }
            memset(f,0,sizeof(f));
            int w=1,p=0;
            f[w][0][0][0][0]=1;
            int i,j,x,y,z;
            for(i=n;i;i--){
                swap(w,p);
                memset(f[w],0,sizeof(f[w]));
                for(j=1;j<=n-i+1&&j<=m;j++)
                    for(x=1;x<=n-i+1&&x<=r;x++)
                        for(y=1;y<=n-i+1&&y<=c;y++)
                            for(z=1;z<=n-i+1&&z<=l;z++){
                                upd(f[w][j][x][y][z],(i64)f[p][j][x][y][z]*max(0,x*y*z-(n-i))%P);
                                upd(f[w][j][x][y][z],(i64)f[p][j][x-1][y][z]*(r-x+1)*y*z%P);
                                upd(f[w][j][x][y][z],(i64)f[p][j][x][y-1][z]*x*(c-y+1)*z%P);
                                upd(f[w][j][x][y][z],(i64)f[p][j][x][y][z-1]*x*y*(l-z+1)%P);
                                upd(f[w][j][x][y][z],(i64)f[p][j][x][y-1][z-1]*x*(c-y+1)*(l-z+1)%P);
                                upd(f[w][j][x][y][z],(i64)f[p][j][x-1][y][z-1]*(r-x+1)*y*(l-z+1)%P);
                                upd(f[w][j][x][y][z],(i64)f[p][j][x-1][y-1][z]*(r-x+1)*(c-y+1)*z%P);
                                upd(f[w][j][x][y][z],(i64)f[p][j-1][x-1][y-1][z-1]*(r-x+1)*(c-y+1)*(l-z+1)%P);
                            }
            }
            p=1;
            for(i=1;i<=n;i++)
                p=(i64)p*i%P;
            printf("%d
    ",(i64)f[w][m][r][c][l]*pwr(p,P-2)%P);
        }
        return 0;
    }

    AC:

    容斥,钦定几个点为极大值点,其他不管,然后用组合数作为系数同时算本质相同的方案。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    typedef long long i64;
    const int N=5e6+6;
    const int P=998244353;
    
    int pwr(int x,int a){
        int s=1;
        for(;a;a>>=1,x=1ll*x*x%P)
            if(a&1)s=1ll*s*x%P;
        return s;
    }
    
    int inv[N],iinv[N];
    int sinv[N],siinv[N];
    int v[N],f[N];
    
    int C(int n,int m){
        return 1ll*inv[n]*iinv[m]%P*iinv[n-m]%P;
    }
    
    int main()
    {
        int i;
        inv[0]=1;
        for(i=1;i<N;i++)
            inv[i]=1ll*inv[i-1]*i%P;
        iinv[N-1]=pwr(inv[N-1],P-2);
        for(i=N-1;i;i--)
            iinv[i-1]=1ll*iinv[i]*i%P;
        int T;
        scanf("%d",&T);
        while(T--){
            int c,r,h,m;
            scanf("%d%d%d%d",&c,&r,&h,&m);
            int n=min(min(c,r),h);
            int sv=1ll*c*r%P*h%P;
            for(i=1;i<=n;i++)
                v[i]=(P+sv-1ll*(c-i)*(r-i)%P*(h-i)%P)%P;
            for(i=1;i<=n;i++)
                f[i]=1ll*C(r,i)*C(c,i)%P*C(h,i)%P*pwr(inv[i],3)%P;
            sinv[0]=1;
            for(i=1;i<=n;i++)
                sinv[i]=1ll*sinv[i-1]*v[i]%P;
            siinv[n]=pwr(sinv[n],P-2);
            for(i=n;i;i--)
                siinv[i-1]=1ll*siinv[i]*v[i]%P;
            int ans=0,d;
            for(i=m,d=1;i<=n;i++,d=P-d)
                (ans+=1ll*d*C(i,m)%P*f[i]%P*siinv[i]%P)%=P;
            printf("%d
    ",ans);
        }
        return 0;
    }

     珍珠:

    O(nd):

    只跟奇偶性有关。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    typedef long long i64;
    const int P=998244353;
    const int S=5e7+7;
    const int N1=4e3+3;
    
    int f[N1][N1];
    
    int main()
    {
        int d,n,m,i,j;
        scanf("%d%d%d",&d,&n,&m);
        if((i64)d*n<S){
            f[0][0]=1;
            for(i=1;i<=n;i++)
                for(j=0;j<=d;j++){
                    if(j)f[i][j]+=(i64)f[i-1][j-1]*(d-j+1)%P,
                    f[i][j]%=P;
                    if(j!=d)f[i][j]+=(i64)f[i-1][j+1]*(j+1)%P,
                    f[i][j]%=P;
                }
            int ans=0;
            for(i=0;i<=n-2*m&&i<=d;i++)
                ans+=f[n][i],ans%=P;
            printf("%d",ans);
            return 0;
        }
        return 0;
    }
  • 相关阅读:
    SDN实验2:Mininet 实验——拓扑的命令脚本生成
    2020软工实践第一次作业
    POJ2942-Knights of the Round Table
    POJ1966 ZOJ2182<无向图点连通度 Isap版>
    POJ1523(求割点)
    POJ2391(最大流Isap+Floyd+二分)
    POJ1087 ZOJ1157(最大流Isap+map映射)
    POJ1459(最大流Isap)
    数字的字符串处理 (转)
    POJ2112 最大流(Isap+Floyd+二分)
  • 原文地址:https://www.cnblogs.com/wanghaoyu/p/CTSC2019.html
Copyright © 2011-2022 走看看