暑假集训CSP提高模拟10

暑假集训CSP提高模拟10

组题人: @worldvanquisher

T1 P170. 黑暗型高松灯 0pts

  • 原题: CF1025G Company Acquisitions
  • 科技题目,直接贺官方题解了。

    考虑势能函数。如果我们使得每操作一步期望势能 1,那么初势能减末势能就是答案。

    设一个点有 x 个儿子的势能为 f(x),那么考虑现在选中两个儿子个数为 x,y 的:

    12(f(x+1)+yf(0))+12(f(y+1)+xf(0))f(x)f(y)=1

    不妨令 f(0)=0 (其实好像是随意定的),那么同构一下得到 f(x)=12x,初减末即可。

    其实是有应用条件的,但是大多数时候是你觉得能用就能用。详见 https://www.cnblogs.com/C202044zxy/p/16340757.html 第一道例题

    部分分尊重原题。

T2 P168. 速度型高松灯 95pts

  • 原题: luogu P3216 [HNOI2011] 数学作业

  • Fn=[nfn1] ,容易有 Fn=F10k11×[110010k0111]n(10k11) ,其中 n[10k1,10k)

  • 因为 k[0,log10n+2] ,每个 k 单独算就行了。

    点击查看代码
    #define ll __int128_t
    struct Matrix
    {
        ll ma[5][5];
        Matrix()
        {
            memset(ma,0,sizeof(ma));
        }
    }f,a;
    Matrix mul(Matrix a,Matrix b,ll n,ll m,ll k,ll p)
    {
        Matrix c;
        for(ll i=1;i<=n;i++)
        {
            for(ll j=1;j<=k;j++)
            {
                for(ll h=1;h<=m;h++)
                {
                    c.ma[i][j]=(c.ma[i][j]+a.ma[i][h]*b.ma[h][j]%p)%p;
                }
            }
        }
        return c;
    }
    Matrix qpow(Matrix a,ll b,ll p,ll n)
    {
        Matrix ans;
        for(ll i=1;i<=n;i++)
        {
            ans.ma[i][i]=1;
        }
        while(b)
        {
            if(b&1)
            {
                ans=mul(ans,a,n,n,n,p);
            }
            b>>=1;
            a=mul(a,a,n,n,n,p);
        }
        return ans;
    }
    int main()
    {
        ll b,p,n=1,m=3,k=3,i;
        scanf("%lld%lld",&b,&p);
        f.ma[1][3]=1;
        for(i=10;i/10<=b;i*=10)
        {
            a.ma[1][1]=a.ma[1][2]=a.ma[3][1]=a.ma[3][2]=a.ma[3][3]=1;
            a.ma[2][2]=i%p;
            f=mul(f,qpow(a,min(i,b+1)-i/10,p,m),n,m,k,p);
        }
        printf("%lld\n",f.ma[1][2]);
        return 0;
    }
    

T3 P169. 力量型高松灯 0pts

  • 原题: luogu P6156 简单题 | luogu P6222 「P6156 简单题」加强版

  • 部分分

    • 20pts :暴力枚举即可,时间复杂度为 O(n2logn+nlogk) ,可以使用扩展欧拉定理优化,使时间复杂度为 O(n2log2n+nlogp)
  • 正解

    • 因涉及变量重名问题,以下所写的 m 指本题的 k
    • 推式子,有 i=1nj=1n(i+j)mμ2(gcd(i,j))gcd(i,j)=k=1nμ2(k)ki=1nj=1n(i+j)m[gcd(i,j)=k]=k=1nμ2(k)ki=1nkj=1nk(ik+jk)m[gcd(i,j)=1]=k=1nμ2(k)km+1i=1nkj=1nk(i+j)md|gcd(i,j)μ(d)=k=1nμ2(k)km+1d=1nkμ(d)i=1nkdj=1nkd(id+jd)m=k=1nμ2(k)km+1d=1nkμ(d)dmi=1nkdj=1nkd(i+j)m=T=1nTmk|Tμ2(k)μ(Tk)ki=1nTj=1nT(i+j)m
    • {s(n)=i=1nj=1n(i+j)mh(i)=imf(n)=i=1nh(i)g(n)=i=1nf(i) ,数形结合有 s(n)=s(n1)+f(2n)+f(2n1)2f(n)=g(2n)2g(n) 。每个数单独计算其 h 值时间复杂度不可接受,我们发现 h 为完全积性函数,可以线筛预处理,也可以使用扩展欧拉定理优化。
    • 原式可以写作 =T=1ns(nT)Tmk|Tμ2(k)μ(Tk)k
    • w(n)=nmd|nμ2(d)μ(nd)d ,显然 w 为积性函数。现在把关注点放在后面的 μ2(k)μ(Tk) 上,二者必须同时为 1 才对答案产生贡献,即 k,Tk 均没有平方质因子,那么 T 就不能有一个质因子的次数 3 ,线筛时记录下次数即可。
      • {w(p)=pm(p1)w(p2)=p2m×(p)
    • 维护 w 的前缀和,整除分块维护 nT 即可。
    • 略卡空间,无用空间回收利用。
    点击查看代码
    const ll p=998244353,phi=998244352;
    ll prime[10000010],h[10000010],w[10000010],len=0;
    bool vis[10000010];
    ll qpow(ll a,ll b,ll p)
    {
        ll ans=1;
        while(b)
        {
            if(b&1)
            {
                ans=ans*a%p;
            }
            b>>=1;
            a=a*a%p;
        }
        return ans;
    }
    void isprime(ll n,ll k)
    {
        memset(vis,0,sizeof(vis));
        h[1]=w[1]=1;
        for(ll i=2;i<=2*n;i++)
        {
            if(vis[i]==0)
            {
                len++;
                prime[len]=i;
                h[i]=qpow(i,k,p);
                w[i]=i-1;
            }
            for(ll j=1;j<=len&&i*prime[j]<=2*n;j++)
            {
                vis[i*prime[j]]=1;
                h[i*prime[j]]=h[i]*h[prime[j]]%p;
                if(i%prime[j]==0)
                {
                    w[i*prime[j]]=((i/prime[j])%prime[j]!=0)*w[i/prime[j]]*(-prime[j]+p)%p;	
                    break;
                }
                else
                {
                    w[i*prime[j]]=w[i]*(prime[j]-1)%p;//乘以 w[prime[j]]
                }
            }
        }
        for(ll i=1;i<=n;i++)
        {
            w[i]=(w[i-1]+w[i]*h[i]%p)%p;//求 w 的前缀和
        }
        for(ll i=1;i<=2*n;i++)
        {
            h[i]=(h[i-1]+h[i])%p;//求 f
        }
        for(ll i=1;i<=2*n;i++)
        {
            h[i]=(h[i-1]+h[i])%p;//求 g
        }
    }
    ll s(ll x)
    {
        return (h[2*x]-2*h[x]%p+p)%p;//求 s
    }
    ll ask(ll n)
    {
        ll ans=0,l,r;
        for(l=1,r;l<=n;l=r+1)
        {
            r=(n/l>=1)?min(n/(n/l),n):n;
            ans=(ans+(w[r]-w[l-1]+p)%p*s(n/l)%p)%p;
        }
        return ans;
    }
    int main()
    {
        ll n,k;
        cin>>n>>k;
        k%=phi;//扩展欧拉定理
        isprime(n,k);
        cout<<ask(n)<<endl;
        return 0;
    }
    

T4 P167. 高松灯 100pts

  • 数位 DP 板子。

    点击查看代码
    ll a[25],f[25][180],sum=0;
    ll divide(ll n,ll a[])
    {
        ll len=0;
        while(n)
        {
            len++;
            a[len]=n%10;
            n/=10;
        }
        return len;
    }
    ll dfs(ll pos,ll pre,ll lead,ll limit)
    {
        if(pos<=0)
        {
            return pre;
        }
        if(f[pos][pre]!=-1&&lead==0&&limit==0)
        {
            return f[pos][pre];
        }
        ll ans=0,maxx=(limit==0)?9:a[pos],i;
        for(i=0;i<=maxx;i++)
        {
            ans=max(ans,dfs(pos-1,pre+i,(i==0)*lead,(i==maxx)*limit));
        }
        return (lead==0&&limit==0)?f[pos][pre]=ans:ans;
    }
    ll ask(ll n)
    {
        ll len=divide(n,a);
        return dfs(len,0,1,1);
    }
    int main()
    {
        ll n;
        cin>>n;
        memset(f,-1,sizeof(f));
        cout<<ask(n)<<endl;
        return 0;
    }
    
  • 最终答案只会来自两种情况,一种是原数,一种是首位放 1 其余全是 9 ,二者取 max 即可。

总结

  • 赛时历程:先溜了一眼题, T1 直接弃掉, T2 之前做过但细节有点多, T3 可以骗点分, T4 之前做过类似的且几乎是数位 DP 纯板子。遂先写 T4 ,因为太过着急导致少打了个负号,少搜了许多状态,花 20min 才调出来;然后写 T2 ,式子因为之前写的时候有点麻烦,遂写了个简单点的,但还是在调细节,调了 1h ;接着是 T3 ,推到最后发现漏了一个 gcd(i,j)=1 导致预处理直接死掉,交了个暴力上去; T1 特判了两种情况。
  • T2 枚举 10k 时炸 long long 了,挂了 5pts
  • T3 暴力预处理 i=1nj=1n[gcd(i,j)=1]×(i+j)k 时空间开大了,再次 MLE ,挂了 20pts

后记

  • 难度不单调递增。

  • 因赛时能过 T1 太过逆天,所以奖励也很逆天。

  • @joke3579 学长让 @int_R 上台评价这场比赛,还开玩笑说要不少于六百字,且还拍视频给 @worldvanquisher

posted @   hzoi_Shadow  阅读(95)  评论(4编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
扩大
缩小
点击右上角即可分享
微信分享提示