BZOJ1799-[Ahoi2009]self 同类分布


题解:
我们统计前面的模数?
按照平常的思维,会定义 dp[i][j][k] d p [ i ] [ j ] [ k ] 为当前扫到前i位,数位和为 j j ,数字取模数位和后为k,跑一遍 R R dp再跑一遍 L1 L − 1 dp d p
然而跑一遍是不行的…因为前面的取模和后面的取模没有关系,之间是不能转移的….
那该如何思考?
所以这道题需要枚举数位和(也就是模数),对每个数位和都跑一次 dfs d f s ,因为数字在 longlong l o n g l o n g 范围内,数位和最大只会有 918=162 9 ∗ 18 = 162 ,是可过的。
Code: C o d e :

#include<bits/stdc++.h> 
#define ll long long
using namespace std;
ll f[21][200][200][2],a,b;
int n,sum=9*18+1,dight[20];
ll find(ll x,int mod)
{
    if(!x)return 0;
    memset(f,0,sizeof(f));
    int num=0;
    while(x)
    {
        dight[++num]=x%10;
        x/=10;
    }
    f[num+1][0][0][0]=1;
    for(int i=num+1;i>1;i--)
        for(int j=0;j<=mod;j++)
            for(int k=0;k<mod;k++)
            {
                if(!f[i][j][k][0]&&!f[i][j][k][1])continue;
                for(int p=0;p<=9;p++)
                {
                    if(p<dight[i-1]&&(j+p<=mod))f[i-1][j+p][(10*k+p)%mod][1]+=f[i][j][k][0];else
                        if(p==dight[i-1]&&(j+p<=mod))f[i-1][j+p][(10*k+p)%mod][0]+=f[i][j][k][0];
                    if(f[i][j][k][1]&&(j+p<=mod)) f[i-1][j+p][(10*k+p)%mod][1]+=f[i][j][k][1];
                }
            }
    return f[1][mod][0][0]+f[1][mod][0][1];
}
int main()
{
    scanf("%lld%lld",&a,&b);
    ll ans=0;
    for(int i=1;i<sum;i++)
        ans+=find(b,i)-find(a-1,i);
    printf("%lld\n",ans);
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jack-Oran

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值