• HDU4507 吉哥系列故事――恨7不成妻(数位dp)


    这题的思路并不难,但是非常难做对,因为取模太恶心了,随时随地会溢出,并且因为取模的级别低,所以要多框括号防止先乘了再取模,还是会溢出

    总之所有地方都取模,并且c++的模数可能是负数,所以需要手写一个mod,防止变成负数。

    做法本身就是一个数位dp,这里要求平方和,我们之前一般做的都是求个数,按照求个数的方法来说,这题应该设计成f[][][][]表示前i个,最高位写j,整个数mod7的余数是k,各位之和的余数是l这样的状态

    但是这题要求的是平方和,我们知道所有的数都可以表示成j*10^(i-1)+A,这个A代表最高位除外的数大小,这样通过高中所学的平方展开,就能发现我们需要保存的是个数,一位和以及平方和,才能求出这个式子

    而预处理的状态就通过我们展开式就能发现了。

    主要是取模太恶心了,真的恶心

    #include<iostream>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int N=20;
    const int p=1e9+7;
    struct node{
        ll s1;
        ll s2;
        ll s3;
    }f[N][10][8][8];
    int power7[N], power9[N];
    int mod(ll a,int b){
        return (a%b+b)%b;
    }
    void init(){
        int i,j,k,l,r;
        for(i=0;i<=9;i++){
            if(i==7)
            continue;
            f[1][i][i%7][i%7].s1+=1;
            f[1][i][i%7][i%7].s2+=i;
            f[1][i][i%7][i%7].s3+=i*i;
        }
        ll power=10;
        for(i=2;i<N;i++,power*=10){
            for(j=0;j<=9;j++){
                if(j==7)
                continue;
                for(k=0;k<7;k++){
                    for(l=0;l<7;l++){
                        for(r=0;r<=9;r++){
                            if(r==7)
                            continue;
                            auto &v1 = f[i][j][k][l], &v2 = f[i - 1][r][mod(k - j * power, 7)][mod(l - j, 7)];
                            v1.s1=mod(v1.s1+v2.s1,p);
                            v1.s2=mod(v1.s2+j*(power%p)%p*v2.s1%p+v2.s2,p);
                            //v1.s3 = mod(v1.s3 + j * j * (power % p) % p* (power % p)%p* v2.s1 + v2.s3 + 
                            //2 * j * power % p * v2.s2, p);
                            v1.s3=mod(v1.s3+j*(power%p)%p*(power%p)%p*j*(v2.s1%p)+2*j*power%p*v2.s2%p+v2.s3,p);
                        }
                    }
                }
            }
        }
        power7[0] = 1;
        for (int i = 1; i < N; i ++ ) power7[i] = power7[i - 1] * 10 % 7;
        power9[0] = 1;
        for (int i = 1; i < N; i ++ ) power9[i] = power9[i - 1] * 10ll % p;
    }
    node get(int i, int j, int a, int b){
        int s3= 0, s1 = 0, s2 = 0;
        for (int x = 0; x < 7; x ++ )
            for (int y = 0; y < 7; y ++ )
                if (x != a && y != b)
                {
                    auto v = f[i][j][x][y];
                    s1= (s1 + v.s1) % p;
                    s2= (s2 + v.s2) % p;
                    s3= (s3 + v.s3) % p;
                }
        return {s1, s2, s3};
    }
    ll dp(ll n){
        if(!n)
        return 0;
        vector<int> num;
        ll sign=n%p;
        while(n){
            num.push_back(n%10);
            n/=10;
        }
        ll res=0;
        ll last1=0;
        ll last2=0;
        int i;
        for(i=num.size()-1;i>=0;i--){
            int x=num[i];
            int j;
            for(j=0;j<x;j++){
                if(j==7)
                continue;
                int a=mod(-last1*power7[i+1],7);
                int b=mod(-last2,7);
                auto v=get(i+1,j,a,b);
                 res = mod(
                    res + 
                    (last1%p)*(last1%p)%p*power9[i + 1]%p*power9[i + 1]%p * v.s1 % p + 
                    v.s3 + 
                    2*last1%p * power9[i + 1]%p*v.s2,
                p);
            }
            if(x==7)
            break;
            last1=10*last1+x;
            last2+=x;
            if(!i&&(last1%7)&&(last2%7)){
               res=mod(res+sign%p*sign%p,p); //如果sign不在之前取模一次,这里会溢出,除非注意取模的优先级
            }
            
        }
        return res;
    }
    int main(){
        ll l,r;
        int t;
        cin>>t;
        init();
        while(t--){
            cin>>l>>r;
            cout<<mod(dp(r)-dp(l-1),p)<<endl;
        }
    }
    View Code
  • 相关阅读:
    linq to sql的性能和reader相比只是差一点点吗
    Win11删除右键菜单open in windows Terminal
    jdk1.8
    mvcc read view
    javascript 跨域双向通信方案,通过postMessage和window.name实现
    [原创]如何加载动态库、获取方法委托、卸载动态库
    awseks创建与使用
    aiops 调研
    consul调研
    机器学习调研
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12675696.html
Copyright © 2020-2023  润新知