dp数组存放结构体,看到平方要想到拆项
debug:p[]数组是mod 1e9 + 7, 不是mod7,在求preval的时候不能用这个数组。debug好久难受了。。。
题意:
如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关——
1、整数中某一位是7;
2、整数的每一位加起来的和是7的整数倍;
3、这个整数是7的整数倍;
要求一个区间中和7无关的数的平方和。
分析:
需要用数位DP维护3个值:
1.与7无关的数的个数
2.与7无关的数的和
3、与7无关的数的平方和。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//typedef __int128 lll;
#define close() ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define mem(a, b) memset(a, b, sizeof(a))
const ll mod = 1e9 + 7;
const int maxn = 1e6;
const int inf = 0x3f3f3f3f;
struct node
{
ll num, sum, sqsum;
node(ll a = 0, ll b = 0, ll c = 0) : num(a), sum(b), sqsum(c){}
};
int v[30];
node dp[30][10][10];
ll p[30];
void init()
{
for(int i = 0; i < 30; i++)
for(int j = 0; j < 10; j++)
for(int k = 0; k < 10; k++)
dp[i][j][k] = node(-1, 0, 0);
p[0] = 1;
for(int i = 1; i < 30; i++)
p[i] = 10 * p[i - 1] % mod;
}
node dfs(int pos, int sum, ll preval, int limit)
{
if(!pos) return sum && preval ? node(1, 0, 0) : node(0, 0, 0);
if(!limit && ~dp[pos][sum][preval].num) return dp[pos][sum][preval];
int up = limit ? v[pos] : 9;
node res = node(0, 0, 0);
for(int i = 0; i <= up; i++)
{
if(i == 7) continue;
int nowsum = (sum + i) % 7;
ll nowval = preval + i * (ll)pow(10, pos - 1); nowval %= 7;
node tmp = dfs(pos - 1, nowsum, nowval, limit && i == up);
res.num += tmp.num, res.num %= mod;
res.sum += (tmp.num * (i * p[pos - 1] % mod) % mod + tmp.sum) % mod, res.sum %= mod;
res.sqsum += (tmp.sqsum + 2 * i * p[pos - 1] % mod * tmp.sum % mod) % mod, res.sqsum %= mod;
res.sqsum += tmp.num * (i * p[pos - 1] % mod) % mod * (i * p[pos - 1] % mod) % mod, res.sqsum %= mod;
}
if(!limit) dp[pos][sum][preval] = res;
return res;
}
ll solve(ll x)
{
int len = 0;
while(x)
{
v[++len] = x % 10;
x /= 10;
}
return dfs(len, 0, 0, 1).sqsum;
}
int main()
{
int t; cin >> t;
init();
while(t--)
{
ll l, r;
cin >> l >> r;
cout << ((solve(r) - solve(l - 1)) + mod) % mod << endl;
}
}