K-lucky-number(0917)
问题描述
K-lucky-number is defined as add up the number of each bit is a multiple of K.for example, 24 is a 3-lucky-number,because 2+4=6, 6 is a multiple of 3.Now, there is a closed interval from L to R, please output the sum of squares of the K-lucky-number in this interval.
输入
The first line of input is the number of test cases T.
For each test case have one line contains three integer L, R, K(0<L<=R<10^9, 1<k<30).
输出
For each test case output the answer the sum of squares of the K-lucky-number in this interval and mod 1000000007.
样例输入
2
1 10 6
100 1000 7
样例输出
36
46057247
有点6、= =
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
#define ll long long
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define N 50 struct Node{
ll cnt,sum,sqsum; //个数,和,平方和
}; int l,r,k;
int bit[N];
ll p10[N];
Node dp[N][N]; void init()
{
p10[]=;
for(int i=;i<=;i++) p10[i]=p10[i-]*%MOD;
}
Node dfs(int pos,int mod,bool limit)
{
Node ans;
ans.cnt=ans.sum=ans.sqsum=;
if(pos==-){
if(!mod) ans.cnt=;
else ans.cnt=;
return ans;
}
if(!limit && dp[pos][mod].sum!=-) return dp[pos][mod];
int end=limit?bit[pos]:;
for(int i=;i<=end;i++){
Node tmp=dfs(pos-,(mod+i)%k,(i==end)&&limit);
ans.cnt=(ans.cnt+tmp.cnt)%MOD;
ans.sum=(ans.sum + tmp.sum + i*p10[pos]%MOD*tmp.cnt%MOD)%MOD;
ans.sqsum=(ans.sqsum + i*i*p10[pos]%MOD*p10[pos]%MOD*tmp.cnt%MOD + *i*p10[pos]%MOD*tmp.sum%MOD + tmp.sqsum)%MOD;
}
if(!limit) dp[pos][mod]=ans;
return ans;
}
ll solve(int n)
{
int len=;
while(n){
bit[len++]=n%;
n/=;
}
return dfs(len-,,).sqsum;
}
int main()
{
init();
int T;
scanf("%d",&T);
while(T--)
{
memset(dp,-,sizeof(dp));
scanf("%d%d%d",&l,&r,&k);
printf("%lld\n",(solve(r)-solve(l-)+MOD)%MOD);
}
return ;
}