• 洛谷P4127 [AHOI2009]同类分布 题解


    洛谷P4127 [AHOI2009]同类分布 题解

    题目链接:P4127 [AHOI2009]同类分布

    题意

    给出两个数 a , b a,b a,b ,求出 [ a , b ] [a,b] [a,b] 中各位数字之和能整除原数的数的个数。

    对于所有的数据, 1 ≤ a ≤ b ≤ 1 0 18 1 ≤ a ≤ b ≤ 10^{18} 1ab1018

    明天就期末考了非但不复习还在刷题 qwqqwqwq

    因为我们不能确切知道每个数的数位和

    但是我们知道它们一定在 [ 1 , 9 × l ] [1,9 \times l] [1,9×l] 的范围内( l l l 为最长的位数)

    我们枚举所有的数位和并计算每个数位和对应的答案

    把这些答案加起来就是 [ 0 , x ] [0,x] [0,x] 的答案

    [ a , b ] [a,b] [a,b] 的答案可以拆分为两个询问 [ 0 , b ] [0,b] [0,b] [ 0 , a − 1 ] [0,a-1] [0,a1]

    而这里 a , b ≤ 1 0 18 a,b \le 10^{18} a,b1018 ,直接压入状态显然不可接受

    于是我们可以考虑记录模当前枚举的数位和意义下的数

    方便起见,我们称当前枚举的数位和为 m m m

    f i , j , k f_{i,j,k} fi,j,k 表示只考虑前 i i i 位数(包括前导零),前 i i i 位的数位和为 j j j ,当前数模 m m m k k k 时的答案

    不难发现
    f i , j , k = ∑ 0 ≤ d ≤ t f i + 1 , j + d , ( k × 10 + d    m o d    m ) f_{i,j,k} = \sum_{0 \le d \le t} f_{i+1,j+d,\left(k\times 10 + d \, \bmod \, m\right)} fi,j,k=0dtfi+1,j+d,(k×10+dmodm)
    其中 t t t 为第 i + 1 i+1 i+1 位的高位限制

    用记搜写法能简洁不少

    时间复杂度 O ( 9 3 × l 4 ) O(9^3\times l^4) O(93×l4)

    代码:

    #include <iostream>
    #include <string>
    #include <vector>
    #include <algorithm>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <iomanip>
    using namespace std;
    #define int long long
    #define INF 0x3f3f3f3f3f3f3f3f
    #define N (int)()
    
    int len,num[25],f[25][205][205];
    int dfs(int u,int sum,int st,int limit,int p)
    {
        if(u>len)
        {
            if(!sum)return 0;
            return st==0&&sum==p;
        }
        if(!limit&&f[u][sum][st]!=INF)
            return f[u][sum][st];
        int up=limit?num[len-u+1]:9;
        int res=0;
        for(int i=0; i<=up; i++)
            res+=dfs(u+1,sum+i,(10*st+i)%p,limit&&i==up,p);
        return limit?res:f[u][sum][st]=res;
    }
    int solve(int x)
    {
        int res=0; len=0;
        while(x) num[++len]=x%10,x/=10;
        for(int m=1; m<=9*len; m++)
        {
            memset(f,0x3f,sizeof(f));
            res+=dfs(1,0,0,1,m);
        }
        return res;
    }
    signed main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0);cout.tie(0);
        // freopen("check.in","r",stdin);
        // freopen("check.out","w",stdout);
        int l,r; cin >> l >> r;
        cout << solve(r)-solve(l-1) << '\n';
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    没事反正whk暂时开摆了

    转载请说明出处

  • 相关阅读:
    十个开发人员面临的最常见的JavaScript问题总结
    10.4 认识Capstone反汇编引擎
    9.复杂的例子:模块的使用和自定义模块
    【数据结构】优先级队列 - 堆
    机器学习——boosting之XGBoost(未完)
    【Linux】驱动_1_hello驱动
    【Eclipse】查看版本号
    规则调优必备技能——捞取更多好人,卡住更多坏人
    JavaScript 的新数组分组方法
    一致性hash算法的应用与go语言实现
  • 原文地址:https://blog.csdn.net/qq_50332374/article/details/125629959