zoukankan      html  css  js  c++  java
  • 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;
    }
    
     
    
    卷也卷不过,躺又躺不平
  • 相关阅读:
    DGA域名可以是色情网站域名
    使用cloudflare加速你的网站隐藏你的网站IP
    167. Two Sum II
    leetcode 563. Binary Tree Tilt
    python 多线程
    leetcode 404. Sum of Left Leaves
    leetcode 100. Same Tree
    leetcode 383. Ransom Note
    leetcode 122. Best Time to Buy and Sell Stock II
    天津Uber优步司机奖励政策(12月28日到12月29日)
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/13786312.html
Copyright © 2011-2022 走看看