CF595B Pasha and Phone 题解

容斥 + 数学

能被 aiai 整除且开头不为 bibi 的个数 = 能被 aiai 整除的个数 - 能被 aiai 整除且开头为 bibi 的个数。

小于 xx 且被 yy 整除的正整数个数为 x1y+1x1y+1

mid1=10k1ai+1mid1=10k1ai+1 表示能被 aiai 整除的 kk 位电话号码。

加上开头为 bibi 这一条件后,我们可以:能被 aiai 整除且开头不大于 bibi 的个数 - 能被 aiai 整除且开头小于 bibi 个数 = 能被 aiai 整除且开头为 bibi 的个数。

mid2=10k1×bi1ai+1mid2=10k1×bi1ai+1mid3=10k1×(bi+1)1ai+1mid3=10k1×(bi+1)1ai+1,分别对应能被 aiai 整除且开头不大于 bibi 的个数 - 能被 aiai 整除且开头 小于 bibi 个数。

最后得到对应式 ans×(mid1(mid3mid2))ans×(mid1(mid3mid2))

注意到 bi=0bi=0mid3<0mid3<0,因此需要特判,直接 ans×(mid1mid3)ans×(mid1mid3)

View code:

#include<bits/stdc++.h>
using namespace std;

#define int long long
#define ri register int
#define il inline

const int INF=0x3f3f3f3f,N=1e5+10,MOD=1e9+7;
int n,k,len=1,ans=1;
int a[N],b[N];

namespace RW{
    il ll read(){
        ll x=0,y=1;
        char c=getchar();
        while(c<'0'||c>'9'){
            if(c=='-')
                y=-1;
            c=getchar();
        }
        while(c>='0'&&c<='9'){
            x=x*10+c-'0';
            c=getchar();
        }
        return x*y;
    }
using namespace RW;

signed main(){
    n=read(),k=read();
    for(ri i=1;i<=n/k;i++)
        a[i]=read();
    for(ri i=1;i<=n/k;i++)
        b[i]=read();
    for(ri i=1;i<=k;i++)
        len*=10;
    for(ri i=1;i<=n/k;i++){
        int mid1=(len-1)/a[i]+1;
        int mid2=(len/10*b[i]-1)/a[i]+1;
        int mid3=(len/10*(b[i]+1)-1)/a[i]+1;
        if(!b[i])
            ans=ans*(mid1-mid3)%MOD;
        else
            ans=ans*(mid1-mid3+mid2)%MOD;
    }
    printf("%lld",ans);
    return 0;
}
posted @ 2021-11-11 21:55  BFNewdawn  阅读(52)  评论(0)    收藏  举报
编辑推荐:
· Java线程池详解:高效并发编程的核心利器
· 从“看懂世界”到“改造世界”:AI发展的四个阶段你了解了吗?
· 协程本质是函数加状态机——零基础深入浅出 C++20 协程
· 编码之道,道心破碎。
· 记一次 .NET 某发证机系统 崩溃分析
阅读排行:
· 这5种规则引擎,真香!
· 【大数据高并发核心场景实战】 - 数据持久化之冷热分离
· 【附源码】用Spring AI通杀所有MCP客户端,简直离谱!
· 大模型VS小模型:论国产数据库运维AI Agent的正确打开方式
· 【好用推荐】免费在线图片压缩工具,附源码
点击右上角即可分享
微信分享提示