• Codeforces


    题意:求[L,R](1<=L<=R<=9e18)区间中所有能被自己数位上的非零数整除的数的个数

    分析:丛数据量可以分析出是用数位dp求解,区间个数可以转化为sum(R)-sum(L-1)前缀和相减的形式。如果一个数能被所有位上数的最小公倍数(lcm)整除,便是符合要求的数。

    但是直接传递一个数n的话,dp数组肯定开不下。那么怎么让其传递的值更小呢。

    先了解一个等式:  sum%(x*n)%x == sum%x

    可以将一个数枚举到第pos位之前的值视作sum,x是所有位上数的lcm。那么我们可以在dfs递归的时候传递sum%(x*n),这样就能在维护sum%x性质的同时,使sum变得很小。

    x*n怎么取呢?1-9的最小公倍数是2520,显然它作为此处的x*n在空间复杂度上是支持的。

    此时可以确定dp数组是三维的。dp[i][j][k],其代表枚举到第i位,前面所有位组成的数%2520的余数是j,前面所有位上的lcm是k的数位状态下符合要求的个数。

    还有一个问题,20*2520*2520的数组是开不下的。但是第三维有大部分的数都是不会出现的,所以可以对2520的因数离散化,数量是小于50的,空间复杂度是可以承受的。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn =40;
    typedef long long ll;
    ll dp[maxn][2520][50];
    int a[maxn];
    int dic[3000];
    
    ll gcd(ll a,ll b)
    {
        if(b==0) return a;
        return gcd(b,a%b);
    }
    
    void init()
    {
        int MOD=2520,cnt=0;
        for(int i=1;i<=MOD;++i){
            if(MOD%i==0)
                dic[i]=cnt++;
        }
        memset(dp,-1,sizeof(dp));
    }
    
    ll dfs(int pos,int mod=0,int lcm = 1,bool limit=true)
    {
        if (pos==-1) return mod%lcm==0;
        int id =dic[lcm];
        if(!limit && dp[pos][mod][id]!=-1) return dp[pos][mod][id];
        int up = limit?a[pos]:9;
        ll res=0;
        for(int i=0;i<=up;++i){
            if(i) res+=dfs(pos-1,(mod*10+i)%2520,lcm*i/gcd(lcm,i),limit && i==a[pos]);
            else res+=dfs(pos-1,(mod*10)%2520,lcm,limit && i==a[pos]);
        }
        if(!limit) dp[pos][mod][id] = res;
        return res;
    }
    
    ll solve(ll n)
    {
        int pos=0;
        while(n){
            a[pos++]=n%10;
            n/=10;
        }
        return dfs(pos-1);
    }
    
    
    int main()
    {
        #ifndef ONLINE_JUDGE
             freopen("in.txt","r",stdin);
             freopen("out.txt","w",stdout);
        #endif
        init();
        int T;
        scanf("%d",&T);
        while(T--){
            ll L,R;
            scanf("%lld%lld",&L,&R);
            printf("%lld
    ",solve(R)-solve(L-1));
        }
        return 0;
    }
    为了更好的明天
  • 相关阅读:
    分布式服务框架的雪崩问题
    分布式系统中的幂等性
    Exception引起的性能问题
    TFS2017新特性(一)
    云平台架构变迁
    MQ基本概念
    SVN版本管理
    1年内4次架构调整,谈Nice的服务端架构变迁之路
    鏖战双十一-阿里直播平台面临的技术挑战
    统一日志平台初探
  • 原文地址:https://www.cnblogs.com/xiuwenli/p/9396655.html
Copyright © 2020-2023  润新知