• 20231016比赛总结


    比赛链接

    反思

    B

    感觉有点难想,而且要特判!

    C

    没想到正解并不算太难

    题解

    A

    没什么好说的,之前做过类似的题
    时间复杂度 O ( n ln ⁡ n ) O(n\ln n) O(nlnn)

    #include 
    using namespace std;
    const int N=1000100;
    int n,siz[N],sum[N];
    int e[N<<1],ne[N<<1],h[N],idx;
    inline int read(){
        int FF=0,RR=1;
        char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
        for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
        return FF*RR;
    }
    void dfs(int u,int fa){
        siz[u]=1;
        for(int i=h[u];~i;i=ne[i]){
            int v=e[i];if(v==fa) continue;
            dfs(v,u),siz[u]+=siz[v];
        }
    }
    void add(int x,int y){ e[idx]=y,ne[idx]=h[x],h[x]=idx++;}
    int main(){
        freopen("eat.in","r",stdin);
        freopen("eat.out","w",stdout);
        n=read();
        memset(h,-1,sizeof(h));
        for(int i=1;i<n;i++){
            int x=read(),y=read();
            add(x,y),add(y,x);
        }
        dfs(1,-1);
        for(int i=1;i<=n;i++){
            int g=siz[1]/__gcd(siz[1],siz[i]);
            for(int j=g;j<=n;j+=g) sum[j]++;
        }
        int ans=0;
        for(int i=1;i<=n;i++)
            if(siz[1]%i==0) if(sum[i]>=i) ans++;
        printf("%d\n",ans);
        fprintf(stderr,"%d ms\n",int(1e3*clock()/CLOCKS_PER_SEC));
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    B

    有些神的题
    首先考虑 d p dp dp
    但状态不好表示
    我们想到这是一张每个点出度为 1 1 1 的图,那么前 i i i 个点一定会构成若干条链,那么我们不妨记 d p i , j dp_{i,j} dpi,j 为前 i i i 个点,构成了 j j j 条链的方案数
    转移的话对当前点是 L 还是 R 分类讨论即可
    询问 i i i 的答案的话合并前缀和后缀的 d p dp dp 数组即可
    时间复杂度 O ( n 2 ) O(n^2) O(n2)

    #include 
    using namespace std;
    const int N=5100,P=1e9+7,inv2=500000004;
    int n,fac[N],f[N][N],g[N][N];
    char str[N];
    inline int read(){
        int FF=0,RR=1;
        char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
        for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
        return FF*RR;
    }
    int main(){
        freopen("jump.in","r",stdin);
        freopen("jump.out","w",stdout);
        n=read();scanf("%s",str+1);
        if(n==1){ puts("1");exit(0);}
        f[0][0]=1;
        for(int i=1;i<=n;i++){
            if(str[i]=='L')
                for(int j=1;j<=i;j++)
                    f[i][j]=(1ll*f[i-1][j+1]*(j+1)%P*j+1ll*f[i-1][j]*j)%P;
            else
                for(int j=1;j<=i;j++)
                    f[i][j]=(f[i-1][j-1]+1ll*f[i-1][j]*j)%P;
        }
        g[n+1][0]=1;
        for(int i=n;i;i--){
            if(str[i]=='R')
                for(int j=1;j<=n-i+1;j++)
                    g[i][j]=(1ll*g[i+1][j+1]*(j+1)%P*j+1ll*g[i+1][j]*j)%P;
            else
                for(int j=1;j<=n-i+1;j++)
                    g[i][j]=(g[i+1][j-1]+1ll*g[i+1][j]*j)%P;
        }
        fac[0]=1;
        for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%P;
        printf("%d ",g[2][1]);
        for(int i=2;i<n;i++){
            int ans=0;
            for(int j=1;j<i;j++){
                int coef1=1ll*f[i-1][j]*g[i+1][j+1]%P*fac[j+1]%P*fac[j]%P;
                int coef2=1ll*f[i-1][j]*g[i+1][j]%P*fac[j]%P*fac[j]*2%P;
                int coef3=1ll*f[i-1][j]*g[i+1][j-1]%P*fac[j]%P*fac[j-1]%P;
                ans=(1ll*ans+coef1+coef2+coef3)%P;
            }
            printf("%d ",ans);
        }
        printf("%d\n",f[n-1][1]);
        fprintf(stderr,"%d ms\n",int(1e3*clock()/CLOCKS_PER_SEC));
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    C

    我们考虑如何判断一个子矩形不存在两个黑色连通块(假设我们保证它不存在空腔)
    我们把每列中极大的黑色相邻块缩成一个点,然后列与列直接相邻的点之间连边
    如果这个图是一颗树,即 ∣ V ∣ = ∣ E ∣ + 1 |V|=|E|+1 V=E+1,那么它就合法

    我们考虑搜出所有的空腔的,然后在 ( x 2 + 1 , y 2 + 1 ) (x_2+1,y_2+1) (x2+1,y2+1) y 1 − 1 y_1-1 y11 t a g tag tag,不难发现直接双指针 + 桶维护即可
    时间复杂度 O ( n 3 ) O(n^3) O(n3)

    #include 
    #define pb push_back
    using namespace std;
    typedef long long LL;
    const int N=310;
    int n,m,mnx,mny,mxx,mxy;
    char str[N];
    bool a[N][N],vis[N][N];
    struct Node{ int x1,x2,y1,y2;};
    vector<Node> tag[N];
    vector<int> tg[N][N];
    int fx[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
    inline int read(){
        int FF=0,RR=1;
        char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
        for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
        return FF*RR;
    }
    void dfs(int x,int y){
        mnx=min(mnx,x),mny=min(mny,y),mxx=max(mxx,x),mxy=max(mxy,y);
        vis[x][y]=1;
        for(int k=0;k<4;k++){
            int tx=x+fx[k][0],ty=y+fx[k][1];
            if(tx<1||tx>n||ty<1||ty>m||a[tx][ty]||vis[tx][ty]) continue;
            dfs(tx,ty);
        }
    }
    int buc[N*N],totV[N],totE[N],B[N];
    int main(){
        freopen("village.in","r",stdin);
        freopen("village.out","w",stdout);
        n=read(),m=read();
        for(int i=1;i<=n;i++){
            scanf("%s",str+1);
            for(int j=1;j<=m;j++) a[i][j]=str[j]-48;
        }
        for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(!a[i][j]&&!vis[i][j]&&(i==1||i==n||j==1||j==m)) dfs(i,j);
        for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(!a[i][j]&&!vis[i][j]){
            mnx=1e9,mny=1e9,mxx=0,mxy=0;
            dfs(i,j);
            tag[mnx-1].pb({mnx,mxx,mny,mxy});
        }
        int Delta=n+5;
        LL ans=0;
        for(int u=n;u>=1;u--){
            for(Node t:tag[u]) tg[t.x2+1][t.y2+1].pb(t.y1-1);
            memset(totV,0,sizeof(totV));
            memset(totE,0,sizeof(totE));
            memset(B,0,sizeof(B));
            for(int d=u;d<=n;d++){
                for(int i=1;i<=m;i++)
                    if(a[d][i]&&(d==u||!a[d-1][i])){
                        totV[i]++;
                        if(a[d][i-1]) totE[i]++;
                        if(a[d][i+1]&&!(d==u||!a[d-1][i+1])) totE[i+1]++;
                    }
                for(int i=1;i<=m;i++) totV[i]+=totV[i-1],totE[i]+=totE[i-1];
                buc[totV[0]-totE[1]+Delta]++;
                assert(totV[0]-totE[1]+Delta>=0),assert(totV[0]-totE[1]+Delta<(N<<1));
                for(int i=1,j=0;i<=m;i++){
                    for(int t:tg[d][i]) B[i]=max(B[i],t);
                    while(j<B[i]){ buc[totV[j]-totE[j+1]+Delta]--;j++;}
                    assert(totV[i]-totE[i]-1+Delta>=0),assert(totV[i]-totE[i]-1+Delta<N*N);
                    ans+=buc[totV[i]-totE[i]-1+Delta];
                    if(i<m){
                        assert(totV[i]-totE[i+1]+Delta>=0),assert(totV[i]-totE[i+1]+Delta<N*N);
                        buc[totV[i]-totE[i+1]+Delta]++;
                    }
                }
                for(int i=0;i<m;i++) buc[totV[i]-totE[i+1]+Delta]=0;
                for(int i=m;i;i--) totV[i]-=totV[i-1],totE[i]-=totE[i-1];
                for(int i=1;i<=m;i++) B[i]=max(B[i],B[i-1]);
            }
        }
        printf("%lld\n",ans);
        fprintf(stderr,"%d ms\n",int(1e3*clock()/CLOCKS_PER_SEC));
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
  • 相关阅读:
    现代数据栈:高效开发数据,辅助企业决策
    git上传项目到gitee的详细方法
    零基础学前端(五)重点讲解 JavaScript
    深入理解java虚拟机:虚拟机类加载机制(2)
    C语言基础篇 —— 3-2 一文秒懂函数指针
    测试用例的优化与整理:确保软件质量的关键步骤
    MySQL:12-Java中使用MySQL(JDBC)
    信息收集工具 -- weblive
    CT0514是一个完善的单片锂离子电池恒流/恒压线形 电源管理芯片
    SwiftUI 动态岛开发教程之 07 Live Activities实时活动的要求和限制
  • 原文地址:https://blog.csdn.net/djx2021/article/details/133879654