• 2019-2020 ICPC Asia Hong Kong Regional Contest J. Junior Mathematician 题解(数位dp)


    题目链接

    题目大意

    要你在[l,r]中找到有多少个数满足(xequiv f(x)(mod; m))

    (f(x)=sum_{i=1}^{k-1} sum_{j=i+1}^{k}d(x,i)*d(x,j))

    (d(x,i)表示x的第i位数)

    题目思路

    显然是数位dp,然而这个数位dp不能同时存x%m 和f(x)%m

    这样会内存太大存不了,所以存差值即可

    还有这个dfs的时候取模只取一次,不然会t,卡常严重

    代码

    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<string>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<unordered_map>
    #define fi first
    #define se second
    #define debug printf(" I am here
    ");
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int maxn=5e3+5,inf=0x3f3f3f3f,mod=1e9+7;
    const double eps=1e-10;
    char l[maxn],r[maxn];
    int m,base[maxn];
    ll dp[maxn][100][100];
    int lenl,lenr,num[maxn];
    ll dfs(int pos,int pre,int dif,bool flag){
        if(pos==0) return dif==0;
        if(!flag&&dp[pos][pre][dif]!=-1){
            return dp[pos][pre][dif];
        }
        int lim=flag?num[pos]:9;
        ll ans=0;
        for(int i=0;i<=lim;i++){
            ans=ans+dfs(pos-1,(pre+i)%m,((dif+i*base[pos]-i*pre)%m+m)%m,flag&&i==lim);
        }
        ans%=mod;
        if(!flag){
            dp[pos][pre][dif]=ans;
        }
        return ans;
    }
    ll solve1(){
        for(int i=1;i<=lenr;i++){
            num[i]=r[lenr-i+1]-'0';
        }
        return dfs(lenr,0,0,1);
    }
    ll solve2(){
        for(int i=1;i<=lenl;i++){
            num[i]=l[lenl-i+1]-'0';
        }
        return dfs(lenl,0,0,1);
    }
    bool check(){
        int sum1=0,sum2=0,pre=0;
        for(int i=1;i<=lenl;i++){
            sum1=(sum1*10+l[i]-'0')%m;//x%m
            sum2=(sum2+(l[i]-'0')*pre)%m;// f(x)%m
            pre=(pre+l[i]-'0')%m;
        }
        return sum1==sum2;
    }
    signed main(){
        int _;scanf("%d",&_);
        while(_--){
            scanf("%s%s",l+1,r+1);
            scanf("%d",&m);
            lenl=strlen(l+1),lenr=strlen(r+1);
            for(int i=1;i<=max(lenl,lenr);i++){
                for(int j=0;j<m;j++){
                    for(int k=0;k<=m;k++){
                        dp[i][j][k]=-1;
                    }
                }
            }
            base[1]=1;
            for(int i=2;i<=max(lenl,lenr);i++){
                base[i]=base[i-1]*10%m;
            }
            ll ans=((solve1()-solve2()+check())%mod+mod)%mod;
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
     
    
    卷也卷不过,躺又躺不平
  • 相关阅读:
    词法分析程序
    0909关于编译原理
    深度学习中图像检测的评价标准
    【 记忆网络 1 】 Memory Network
    ssm又乱码
    百度地图标注没了
    Fragment与Activity交互(使用Handler)
    在android里用ExpandableListView实现二层和三层列表
    java中outer的使用
    android中使用Http下载文件并保存到本地SD卡
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/13786312.html
Copyright © 2020-2023  润新知