2025多校冲刺省选模拟赛11

2025多校冲刺省选模拟赛11

T1 A. 划分 25pts

  • 部分分

    • 25pts :从低到高考虑每一位的贡献,高精度辅助转移。
    点击查看代码
    int limit;
    char s[3000010];
    struct Big_int
    {
        int c[510];
        void clear()
        {
            memset(c,0,sizeof(c));
        }
        Big_int operator + (const int &another) const
        {
            Big_int tmp=*this;
            tmp.c[another]++;
            for(int i=another;i<=limit;i++)
            {
                if(tmp.c[i]/2==0)  break;
                tmp.c[i+1]+=tmp.c[i]/2;
                tmp.c[i]%=2;
            }
            return tmp;
        }
        bool operator > (const Big_int &another) const
        {
            for(int i=limit;i>=0;i--)
            {
                if(c[i]>another.c[i])  return true;
                if(c[i]<another.c[i])  return false;
            }
            return true;
        }
        void print()
        {
            int _len=limit;
            while(_len>0&&c[_len]==0)  _len--;
            for(int i=_len;i>=0;i--)  printf("%d",c[i]);
            printf("\n");
        }
    }f[2][510];
    Big_int sx_max(Big_int a,Big_int b)
    {
        return a>b?a:b;
    }
    int main()
    {
    #define Isaac
    #ifdef Isaac
        freopen("partition.in","r",stdin);
        freopen("partition.out","w",stdout);
    #endif
        int t,n,m,len,i,j,k;
        scanf("%d",&t);
        for(k=1;k<=t;k++)
        {
            scanf("%d%d%s",&n,&m,s+1);  limit=max(n,m)+1;  len=n+m;
            reverse(s+1,s+1+len);
            memset(f,0,sizeof(f));
            for(i=1;i<=len;i++)
            {
                memset(f[i&1],0,sizeof(f[i&1]));
                for(j=max(0,i-m);j<=min(i,n);j++)
                {
                    f[i&1][j]=f[(i-1)&1][j];
                    if(s[i]=='0')  
                    {
                        if(j-1>=0)  f[i&1][j]=sx_max(f[i&1][j],f[(i-1)&1][j-1]);
                    }
                    else
                    {
                        if(i-j-1>=0)  f[i&1][j]=f[(i-1)&1][j]+(i-j-1);
                        if(j-1>=0)  f[i&1][j]=sx_max(f[i&1][j],f[(i-1)&1][j-1]+(j-1));
                    }
                }
            }
            f[len&1][n].print();
        }
        return 0;
    }
    
    
  • 正解

    • 钦定 nm
    • 考虑这么一个调整过程。先用 a1m 填满 c ,在后续移动过程中如果遇到 0 则比较替换 b 和加入 c 的贡献后贪心选择较大的。每一段极长的 1 和替换 b 得到的 1 单独进行考虑。
    • 正确性比较显然吧?
    点击查看代码
    int x[2000010],y[2000010],z[2000010];
    char s[2000010];
    int find(int pos,int m)
    {
        for(;pos<=m;pos++)  if(y[pos]==1)  return pos;
        return 0x3f3f3f3f;
    }
    int main()
    {
    #define Isaac
    #ifdef Isaac
        freopen("partition.in","r",stdin);
        freopen("partition.out","w",stdout);
    #endif
        int t,n,m,len,limit,cnt,st,ed,i,j,k;
        scanf("%d",&t);
        for(k=1;k<=t;k++)
        {
            scanf("%d%d%s",&n,&m,s+1);  len=n+m;  limit=max(n,m)+1;
            if(n<m)  swap(n,m);
            st=1;  ed=n;  cnt=0;
            for(i=1;i<=limit;i++)  x[i]=y[i]=z[i]=0;
            for(i=1;i<=m;i++)  y[m-i+1]=s[i]-'0';
            for(i=m+1;i<=len;i++)
            {
                if(s[i]=='1')  cnt++;
                else
                {
                    st=find(st,m);
                    if(st<=ed-cnt)  
                    {
                        y[st]=0;  cnt++;
                    }
                    else
                    {
                        for(;cnt>=1;ed--,cnt--)  x[ed]=1;
                        x[ed]=0;  ed--;
                    }
                }
            }
            for(;ed>=1;ed--)  x[ed]=1;
            for(i=1;i<=limit;i++)
            {
                z[i]+=x[i]+y[i];
                z[i+1]+=z[i]/2;
                z[i]%=2;
            }
            for(;limit>1&&z[limit]==0;limit--);
            for(i=limit;i>=1;i--)  printf("%d",z[i]);
            printf("\n");
        }
        return 0;
    }
    
    

T2 B. 树 0pts

  • 部分分

    • 5pts :模拟,需要特判 m=1 的情况。
    点击查看代码
    struct node
    {
        int from,to,w;
        bool operator < (const node &another) const
        {
            return w<another.w;
        }
    };
    int du[210],a[22050];
    vector<node>e;
    struct DSU
    {
        int fa[210];
        void init(int n)
        {
            for(int i=1;i<=n;i++)  fa[i]=i;
        }
        int find(int x)
        {
            return fa[x]==x?x:fa[x]=find(fa[x]);
        }
    }D;
    bool kruskal(int n)
    {
        e.clear();  D.init(n);
        for(int i=1,k=1;i<=n;i++)
        {
            du[i]=0;
            for(int j=i+1;j<=n;j++,k++)  e.push_back((node){i,j,a[k]});
        }
        sort(e.begin(),e.end());
        for(int i=0;i<e.size();i++)
        {
            int x=D.find(e[i].from),y=D.find(e[i].to);
            if(x!=y)
            {
                D.fa[x]=y;
                du[e[i].from]++;  du[e[i].to]++;
            }
        }
        int cnt=0;
        for(int i=1;i<=n;i++)  cnt+=(du[i]%2==1);
        return cnt==2;
    }
    int qpow(int a,int b,int p)
    {
        int ans=1;
        while(b)
        {
            if(b&1)  ans=1ll*ans*a%p;
            b>>=1;
            a=1ll*a*a%p;
        }
        return ans;
    }
    int main()
    {
    #define Isaac
    #ifdef Isaac
        freopen("tree.in","r",stdin);
        freopen("tree.out","w",stdout);
    #endif
        int n,p,l,m,fenzi,fenmu,i;
        cin>>n>>p;
        for(m=1;m<=n;m++)
        {
            l=m*(m-1)/2;  fenzi=fenmu=0;
            for(i=1;i<=l;i++)  a[i]=i;
            do
            {
                if(kruskal(m)==true)  fenzi=(fenzi+1)%p;
                fenmu=(fenmu+1)%p;
            }while(next_permutation(a+1,a+1+l));
            cout<<((m==1)?1:1ll*fenzi*qpow(fenmu,p-2,p)%p)<<endl;
        }
        return 0;
    }
    
    
  • 正解

T3 C. 划分树 5pts

  • 部分分

    • 5pts :爆搜。
    点击查看代码
    const int p=998244353;
    struct node
    {
        int nxt,to,id;
    }e[600010];
    int head[300010],ans[310],vis[300010],broke[300010],siz,maxx,minn,cnt=0;
    void add(int u,int v,int id)
    {
        cnt++;  e[cnt]=(node){head[u],v,id};  head[u]=cnt;
    }
    void dfs(int x)
    {
        vis[x]=1;
        siz++;  maxx=max(maxx,x);  minn=min(minn,x);
        for(int i=head[x];i!=0;i=e[i].nxt)
        {
            if(broke[e[i].id]==0&&vis[e[i].to]==0)  dfs(e[i].to);
        }
    }
    int main()
    {
    #define Isaac
    #ifdef Isaac
        freopen("partition_tree.in","r",stdin);
        freopen("partition_tree.out","w",stdout);
    #endif
        int n,m,k,u,v,s,flag,i;
        cin>>n>>k;  m=n-1;
        for(i=1;i<=m;i++)
        {
            cin>>u>>v;
            add(u,v,i);  add(v,u,i);
        }
        for(s=0;s<(1<<m);s++)
        {
            if(__builtin_popcount(s)<=k)
            {
                flag=1;
                for(int i=1;i<=n;i++)  vis[i]=broke[i]=0;
                for(int i=0;i<m;i++)  broke[i+1]=((s>>i)&1);
                for(int i=1;i<=n;i++)
                {
                    if(vis[i]==0)
                    {
                        siz=maxx=0;  minn=0x3f3f3f3f;
                        dfs(i);
                        if(maxx-minn+1!=siz)
                        {
                            flag=0;
                            break;
                        }
                    }
                }
                ans[__builtin_popcount(s)]=(ans[__builtin_popcount(s)]+flag)%p;
            }
        }
        for(i=0;i<=k;i++)  cout<<ans[i]<<endl;
        return 0;
    }
    
    
  • 正解

总结

posted @   hzoi_Shadow  阅读(40)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探
历史上的今天:
2024-02-14 2024寒假自主提升日记
扩大
缩小
点击右上角即可分享
微信分享提示