HUD 4507 Jige series of stories - Hate is not a wife 7

Portal

Value at $ limit can sense three digits $ dp $, $ dfs $ is to maintain the current position, before you die sum of $ 7 value at $ significance, before filling the mold $ 7 number, whether close to the limit

The main square is now seeking various legal data and, more nausea

Open a square structure maintenance at three things, the number of legitimate number, and, the number of legitimate and legal data

The first two good maintenance, the square and find out that can be opened, such as the next layer $ dfs $ pass up and for the $ x $, the current number of bits to fill the $ k $, consider the square of the number of current and all legal as each square of a number of legal and

Set a certain level pass up a valid number value $ y $, then the value of the current layer is the

$ 10 ^ p \ cdot k + y $, after the square of $ 10 ^ {2p} \ cdot k ^ 2 + y ^ 2 + 2ky \ cdot 10 ^ p $

^ Found the square and in fact the number of legitimate next level after all add up to the $ y 2 $

For $ 2ky \ cdot 10 ^ p $, the $ 2k \ cdot 10 ^ p $ proposed, then we can give all add up to $ y $ is the number of the next layer of legal and

For $ 10 ^ {2p} \ cdot k ^ 2 $, because the addition of a number of several legal next level, then the next level of contribution that is multiplied by the number of legitimate number $ 10 ^ {2p} \ cdot k ^ 2 $

So we can maintain the data of the current position with the next level of data

Specific implementation can look at the code

 

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
inline ll read()
{
    ll x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
    return x*f;
}
const int mo=1e9+7;
inline int fk(int x) { return x>=mo ? x-mo : x; }
ll T,L,R;
struct dat {
    ll tot,sum,sum2;
    dat (ll _tot=0,ll _sum=0,ll _sum2=0) { tot=_tot,sum=_sum,sum2=_sum2; }
    inline dat operator + (const dat &tmp) const {
        return dat(fk(tot+tmp.tot),fk(sum+tmp.sum),fk(sum2+tmp.sum2));
    }
    inline dat operator * (const ll &tmp) const {
        return dat(tot, fk(tot*tmp%mo + sum) , fk( fk((tot*tmp%mo)*tmp%mo + (2ll*tmp%mo)*sum%mo) + sum2 ) );
    }
}f[19][9][9][2];
ll Power[19];
vector <int> V;
dat dfs(int p,int sum,int now,bool lim)
{
    if(!p) return (sum&&now) ? dat(1,0,0) : dat(0,0,0);
    dat &t=f[p][sum][now][lim];
    if(t.tot!=-1) return t;
    t.tot=0;
    for(int k=0;k<=9;k++)
    {
        if(lim&&k>V[p-1]) break;
        if(k==7) continue;
        dat add=dfs(p-1,(sum+k)%7,(now*10+k)%7,lim&(k==V[p-1]));
        t=t + ( add * (Power[p-1]*k%mo) );
    }
    // cout<<p<<" "<<sum<<" "<<now<<" "<<lim<<" "<<t.tot<<" "<<t.sum<<" "<<t.sum2<<endl;
    return t;
}
inline void Clr()
{
    for(int i=1;i<=18;i++)
        for(int j=0;j<7;j++)
            for(int k=0;k<7;k++)
                f[i][j][k][0]=f[i][j][k][1]=dat(-1,0,0);
}
int main()
{
    T=read();
    Power[0]=1; for(int i=1;i<=18;i++) Power[i]=Power[i-1]*10%mo;
    while(T--)
    {
        L=read()-1,R=read();
        ll now=R; V.clear(); Clr();
        while(now) V.push_back(now%10),now/=10;
        ll ans=dfs(V.size(),0,0,1).sum2;
        now=L; V.clear(); Clr();
        while(now) V.push_back(now%10),now/=10;
        printf("%d\n",fk(ans-dfs(V.size(),0,0,1).sum2+mo));
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/LLTYYC/p/11687560.html