您的位置:首页 > 其它

【数位DP】HDU 4507 吉哥系列故事——恨7不成妻

2014-02-24 20:42 148 查看
原题直通车:HDU 4507 吉哥系列故事——恨7不成妻

题意:统计区间中满足下列三个要求的所有数的平方和

1、没有数位是7

2、不是7的倍数

3、各数位和不是7的倍数

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int mod = 1000000007;

struct node {
int sum, num, ans;
void read(int a, int b, int c) {
sum=a, num=b, ans=c;
}
};
node one, zero, rone;
node dp[20][10][10];
__int64 t[20];
int digit[20];
void init() {
one.read(0, 1, 0);
rone.read(0, -1, 0);
zero.read(0, 0, 0);
__int64 p=1;
for(int i=0; i<20; ++i) t[i]=p%mod, p*=10;
for(int i=0; i<20; ++i)
for(int j=0; j<10; ++j)
for(int k=0; k<10; ++k)
dp[i][j][k] = rone;
}
node dfs(int pos, int s, int mo, bool limit) {
if(pos==-1) {
if(s&&mo) return one;
return rone;
}
if(!limit&&dp[pos][s][mo].num!=-1) return dp[pos][s][mo];
int len = (limit?digit[pos]:9);
node ret = zero;
for(int i=0; i<=len; ++i)
if(i!=7) {
__int64 tm = (i*t[pos])%mod;
node rt = dfs(pos-1, (s+i)%7, (mo*10+i)%7, limit&&i==digit[pos]);
if(rt.num == -1) continue;
ret.sum = (ret.sum+rt.num*tm+rt.sum)%mod;
ret.ans = (ret.ans+rt.num*(tm*tm%mod)%mod+2ll*tm*rt.sum%mod+rt.ans)%mod;
ret.num = (ret.num+rt.num)%mod;
}
if(!limit) dp[pos][s][mo] = ret;
return ret;
}
__int64 work(__int64 x) {
int len = 0;
while(x) digit[len++]=x%10, x/=10;
return dfs(len-1, 0, 0, true).ans;
}
int main() {
init();
int T; scanf("%d", &T);
while(T--) {
__int64 l, r;
scanf("%I64d%I64d", &l, &r);
printf("%d\n", (work(r)-work(l-1)+mod)%mod);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: