• 51nod 1232 完美数 数位dp


    题目来源: 胡仁东
    基准时间限制:2 秒 空间限制:131072 KB 
    如果一个数能够被组成它的各个非0数字整除,则称它是完美数。例如:1-9都是完美数,10,11,12,101都是完美数,但是13就不是完美数(因为13不能被数字3整除)。
    现在给定正整数x,y,求x和y之间(包含x和y的闭区间)共有多少完美数。
     
    题目作者为:hrdv
     
    Input
    第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 10000)
    第2 - T + 1行:每行2个数,X, Y中间用空格分割。(1 <= X <= Y <= 10^18)
    Output
    输出共T行,对应区间中完美数的数量。
    Input示例
    2
    1 9
    12 15
    Output示例
    9
    2

    如同Codeforces Beta Round #51 D. Beautiful numbers

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<stack>
    #include<cstring>
    #include<vector>
    #include<list>
    #include<set>
    #include<map>
    using namespace std;
    #define ll long long
    #define pi (4*atan(1.0))
    #define eps 1e-4
    #define bug(x)  cout<<"bug"<<x<<endl;
    const int N=1e2+10,M=1e6+10,inf=2147483647;
    const ll INF=1e18+10,mod=1e7+7;
    ll bit[N],flag[M];
    ll f[N][60][2530];
    void init()
    {
        int s=1;
        for(int i=1;i<=2520;i++)
            if(2520%i==0)
            flag[i]=s++;
    }
    ll dp(int pos,int fl,ll m,ll sum)
    {
        if(pos==0)return (m%sum==0);
        if(fl&&f[pos][flag[sum]][m]!=-1)return f[pos][flag[sum]][m];
        ll x=fl?9:bit[pos];
        ll ans=0;
        for(ll i=0;i<=x;i++)
        {
            if(i)
                ans+=dp(pos-1,fl||i<x,(m*10+i)%2520,(sum*i)/__gcd(sum,i));
            else
                ans+=dp(pos-1,fl||i<x,(m*10+i)%2520,sum);
        }
        if(fl)f[pos][flag[sum]][m]=ans;
        return ans;
    }
    ll getans(ll x)
    {
        int len=0;
        while(x)
        {
            bit[++len]=x%10;
            x/=10;
        }
        return dp(len,0,0,1);
    }
    int main()
    {
        init();
        int T;
        scanf("%d",&T);
        memset(f,-1,sizeof(f));
        while(T--)
        {
            ll l,r;
            scanf("%lld%lld",&l,&r);
            //cout<<getans(r)<<" "<<getans(l)<<endl;
            printf("%lld
    ",getans(r)-getans(l-1));
        }
        return 0;
    }
  • 相关阅读:
    SQL语法分类
    SQL语法入门
    数据库的基本对象
    数据库基础
    数据库概述
    设计模式之备忘录模式
    设计模式之State模式
    设计模式之装饰模式
    简单工厂模式
    初识C#设计模式
  • 原文地址:https://www.cnblogs.com/jhz033/p/6601814.html
Copyright © 2020-2023  润新知