But my words, like si|

MessageBoxA

园龄:4年10个月粉丝:4关注:0

2024-05-24 17:10阅读: 9评论: 0推荐: 0

NOI模拟 GCD

涉及知识点:数位DP,容斥原理

题意

dig(i) 表示 i 十进制表示下各数位乘积,则一个数对是正确的当且仅当满足以下条件:

  • 1i,jn
  • dig(i)×dig(j)>0
  • gcd(dig(i),dig(j))k

给你 n,k (1018) 求有多少正确的有序数对。答案对 998244353​​ 取模。

思路

由于 dig 为“数位”的乘积,我们知道一个 1x9 的数的质因子只有可能为 2,3,5,7,因此乘起来质因子也只有这四个,而且发现这四个质因子个数的有效组合其实只有 104 级别。

fi,j,k,l 为满足 2i×3j×5k×7l|dig(a) 且满足 ana​​ 的个数。这东西可以数位 DP。

那么满足 gcd(dig(a),dig(b))=2i×3j×5k×7l(a,b) 有序数对的个数为:

p1,p2,p3,p40,1fi+p1,j+p2,k+p3,l+p42×(1)p1+p2+p3+p4

这是个容斥式,fi,j,k,l 意味着 x=2x2×3x3×5x5×7x7(x2i,x3j,x5k,x7l),xn 的情况数。

a=2a2×3a3×5a5×7a7,b=2b2×3b3×5b5×7b7 时,我们通过上述容斥式算出了 min(a2,b2)=i,min(a3,b3)=j,min(a5,b5)=k,min(a7,b7)=l 的情况数。具体做法可以理解为用 fi,j,k,l 减去了 (i+1,j,k,l),(i,j+1,k,l),(i,j,k+1,l),(i,j,k,l+1) 这几种情况的并集(也就是 a,b 存在质因子对应的指数取 min 大于我们想要的情况)。

我们又知道 gcd(a,b)=2min(a2,b2)×3min(a3,b3)×5min(a5,b5)×7min(a7,b7),因此就算出来了满足 gcd(dig(a),dig(b))=2i×3j×5k×7l(a,b) 有序数对的个数。

最后遍历一下质因子之积 k 的所有组合统计答案即可。

代码

数位 DP 部分较为容易,直接看代码吧。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL P=998244353;
const int MAXDIG=20;
LL n,K,ans=0,f[MAXDIG][61][39][27][23];
bool vis[MAXDIG][61][39][27][23];
int num[MAXDIG],numlen=0;
LL dfs(int dep,bool zero,bool limit,int i,int j,int k,int l){
    if(i/3+j/2+k+l>dep) return 0;//剪枝
    if(dep==0) return !zero && !i && !j && !k && !l;
    if(!zero && !limit && vis[dep][i][j][k][l]) return f[dep][i][j][k][l];
    int dig=limit?num[dep]:9;
    LL res=0;
    if(zero) res=(res+dfs(dep-1,true,limit&&(dig==0),i,j,k,l))%P;
    for(int p=1;p<=dig;p++){
        res=(res+dfs(dep-1,false,limit&&(dig==p),max(i-(!(p%2))-(!(p%4))-(!(p%8)),0),max(j-(!(p%3))-(!(p%9)),0),max(k-(!(p%5)),0),max(l-(!(p%7)),0)))%P;
    }
    if(!zero && !limit){
        vis[dep][i][j][k][l]=true;
        f[dep][i][j][k][l]=res;
    }
    return res;
}
LL calc(int i,int j,int k,int l){
    LL res=0;
    for(int p2=0;p2<=1;p2++)
    for(int p3=0;p3<=1;p3++)
    for(int p5=0;p5<=1;p5++)
    for(int p7=0;p7<=1;p7++){
        LL tmp=dfs(numlen,true,true,i+p2,j+p3,k+p5,l+p7);
        res=(res+1LL*((p2+p3+p5+p7)%2?P-1:1)*tmp%P*tmp%P)%P;
    }
    return res;
}
int main(){
    // freopen("b.in","r",stdin);
    // freopen("b.out","w",stdout);
    cin>>n>>K;
    while(n){
        num[++numlen]=n%10;
        n/=10;
    }
    LL tmp2,tmp3,tmp5,tmp7;
    tmp2=1;
    for(int i=0;tmp2<=K;i++,tmp2*=2){
        tmp3=1;
        for(int j=0;tmp2*tmp3<=K;j++,tmp3*=3){
            tmp5=1;
            for(int k=0;tmp2*tmp3*tmp5<=K;k++,tmp5*=5){
                tmp7=1;
                for(int l=0;tmp2*tmp3*tmp5*tmp7<=K;l++,tmp7*=7){
                    ans=(ans+calc(i,j,k,l))%P;
                }
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

本文作者:MessageBoxA

本文链接:https://www.cnblogs.com/SkyNet-PKN/p/18211336

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   MessageBoxA  阅读(9)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 evening Corn Wave
  2. 2 Группа крови Кино
  3. 3 The Sound Of Silence Simon & Garfunkel
  4. 4 dB doll YUE.STEVEN
Группа крови - Кино
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.