loj#10168恨 7 不成妻

版权声明:欢迎转载(标记出处),写得不好还请多指教 https://blog.csdn.net/quan_tum/article/details/82146515

这一题的题目描述很…无法描述,但还是能马上看出是一道数位dp题。限制的条件有点多,细节处理起来确实很烦。只要记录合法的数的个数,数的和以及数的平方和。

#include<bits/stdc++.h>
#define ll long long
#define il inline
using namespace std;
const int mo=1e9+7;
#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
il ll read(){
    ll x=0,f=1;char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=(x+(x<<2)<<1)+c-48;
    return x*f;
}
char sr[1<<21],z[20];int C=-1,Z;
il void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
il void print(ll x){
    if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
    while(z[++Z]=x%10+48,x/=10);
    while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
struct A{
    ll s0,s1,s2;
    A(){}
    A(ll a,ll b,ll c):s0(a),s1(b),s2(c){}
}f[20][7][7];
ll c[20],d[20],T,l,r;
il A dfs(int l,int s,int ss,bool o){
    if(l<0) return A(s&&ss,0,0);
    if(!o&&f[l][s][ss].s0!=-1) return f[l][s][ss];
    int r=o?d[l]:9;
    A ans=A(0,0,0);
    for(int i=0;i<=r;++i){
        if(i!=7){
            A t=dfs(l-1,(s+i)%7,(ss*10+i)%7,o&&i==r);
            (ans.s0+=t.s0)%=mo;
            (ans.s1+=(c[l]*i%mo*t.s0%mo+t.s1)%mo)%=mo;
            (ans.s2+=(t.s2+2*c[l]*i%mo*t.s1%mo)%mo)%=mo;
            (ans.s2+=i*c[l]*i%mo*c[l]%mo*t.s0%mo)%=mo;
        }
    }
    if(!o) f[l][s][ss]=ans;
    return ans;
}
void init(){
    c[0]=1;
    for(int i=1;i<20;++i)
    c[i]=(c[i-1]*10)%mo;
}
il ll solve(ll x){
    int l=0;
    while(x){d[l++]=x%10;x/=10;}
    A ans=dfs(l-1,0,0,1);
    return ans.s2;
}
int main(){
    init();T=read();
    memset(f,-1,sizeof(f));
    while(T--){
        l=read(),r=read();
        print((solve(r)-solve(l-1)+mo)%mo);
    }Ot();return 0;
}

猜你喜欢

转载自blog.csdn.net/quan_tum/article/details/82146515