# hdu4507 hates the number of DPS in the trouble of unmarried 7

It took me nearly an afternoon to figure out how to use the square of sub-states and update the square sum of self-states. This problem is nauseating to me...
hdu4507
Let's see. https://blog.csdn.net/LightningUZ/article/details/90619068
Write in super detail.

If an integer meets one of the following three conditions, then we say that the integer is related to 7.——
1. One of the integers is 7.
2. The sum of each digit of an integer is an integer multiple of 7.
3. This integer is an integer multiple of 7.
Now the question arises: Gigo wants to know the square of numbers that are independent of 7 in a certain range.

In the dfs process,
For condition 1, this is certainly the case:

	if(i==7) continue;


For condition 2 and condition 3, this is probably the case:

	if(pos < 0){
if(Bit sum % 7==0 || Sum of numbers % 7 == 0) return 0;
else return 1;
}


So the dimension of dp is pos, bit sum, number sum and total three-dimensional.
Natural dfs also carry upper sum and number sum.

dfs(int pos, bool limit, ll bitmod, ll premod)
//Bit mod is the result of bits and 7 modules, premod is the result of numbers and 7 modules.


The above is not a difficult point. The difficulty lies in that the problem is not to find the number of numbers satisfying the meaning of the question, but the sum of squares of the numbers satisfying the meaning of the question.
How do we update the number of analogies?

tmp = dfs(...);//If dfs returns a number
ans += tmp;//Answers in sub-states update answers in this state
.....
return ans;


From simplicity to difficulty, if the question asks us only sum, not sum of squares, how can we update it?
For example, the number of 13X x x, considering the location of xxx is updated to the second bit, assuming that the second bit is 2. If the number of numbers satisfying the meaning of the question in X is x.cntx.cntx.cnt, and then the sum of these numbers is x.sumx.sum, then the number of numbers satisfying the meaning of the question in the number of 2x2x x must be added with x.cntx.cnt, assuming that the number of cntcntcs is x.cnt.cnt. There are 1-9, so the number of new additions of 2x 2x to satisfy the meaning of the question must be 21-29, that is, every number of satisfying the meaning of the question in x plus 20, so it can update 2x.sum2x.sum2x.sum.
2x.sum+=x.sum+x.cnt This bit is 10pos 2x.sum+=x.sum+x.cnt * This bit is * 10^{pos}2x.sum+=x.sum+x.cnt This bit is 10pos
Let's suppose that the bit of high high high = 10pos is several 10^{pos} * and this bit is several 10pos and this bit is several 10 POS
Through various metaphysical thinking and analogy, we find that the sum of squares is updated in this way:
ans.sum2=∑(tmp.sum2+2∗high∗tmp.sum+high2∗tmp.cnt)ans.sum^2 = \sum(tmp.sum^2 + 2 * high * tmp.sum + high^2 * tmp.cnt)ans.sum2=∑(tmp.sum2+2∗high∗tmp.sum+high2∗tmp.cnt)
(See the blog above if you don't understand it. I don't think I understand orzorzorz.
That is to say, squares are used and numbers are updated together, so we set dp as a structure to save and update three numbers at the same time, and initialize violent initialization.
codecodecode

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;

ll a[25];
struct Node{
ll cnt, sum, sum_2;
Node(ll x = 0, ll y = 0, ll z = 0):cnt(x), sum(y), sum_2(z){};
}dp[25][7][7];

ll pow(ll x){
ll ans = 1, res = 10;
while(x){
if(x&1) ans = ans * res % mod;
res = res * res % mod;
x >>= 1;
}
return ans % mod;
}

inline update(Node &ans, Node &tmp, ll &h){
ans.cnt = (ans.cnt + tmp.cnt) % mod;
ans.sum = (ans.sum + (tmp.cnt * h % mod + tmp.sum) % mod) % mod;
ans.sum_2 = (ans.sum_2 + (tmp.sum_2 + ((2 * h) % mod * tmp.sum) % mod + ((h * h) % mod * tmp.cnt) % mod) % mod) % mod;
}

Node dfs(int pos, bool limit, ll bitmod, ll premod){
if(pos < 0){
if(!bitmod%7 || !premod%7) return Node(0, 0, 0);
else return Node(1, 0, 0);
}
if(!limit && dp[pos][bitmod][premod].cnt != -1) return dp[pos][bitmod][premod];
ll up = limit ? a[pos]:9;
Node ans;
for(ll i = 0; i <= up; i++){
if(i==7) continue;
Node tmp = dfs(pos - 1, limit && i == up, (bitmod + i) % 7, (premod * 10 % 7 + i) % 7);
ll h = i * pow(pos) % mod;
update(ans, tmp, h);
}
if(!limit) dp[pos][bitmod][premod] = ans;
return ans;
}

void init(){
for(int i = 0; i < 25; i++){
for(int j = 0; j < 7; j++)
for(int k = 0; k < 7; k++){
dp[i][j][k] = Node(-1, 0, 0);
}
}
}

ll solve(ll x){
ll pos = 0;
while(x){
a[pos++] = x % 10;
x /= 10;
}
return dfs(pos - 1, true, 0, 0).sum_2 % mod;
}
int main(){
ll n;
ll l, r;
scanf("%lld", &n);
init();
while(n--){
scanf("%lld%lld", &l, &r);
printf("%lld\n", (solve(r) - solve(l - 1) + mod) % mod);
}
return 0;
}


Posted by vb_123 on Tue, 13 Aug 2019 05:41:24 -0700