问题
A number N is given in the range 1 <= N <= 10^50
. A function F(x)
is defined as the sum of all digits of a number x. We have to find the count of number of special pairs (x, y) such that:
1. 0 <= x, y <= N
2. F(x) + F(y)
is prime in nature
We have to count (x, y)
and (y, x)
only once.
Print the output modulo 1000000000 + 7
My approach:
Since the maximum value of sum of digits in given range can be 450 (If all the characters are 9 in a number of length 50, which gives 9*50 = 450
). So, we can create a 2-D array of size 451*451 and for all pair we can store whether it is prime or not.
Now, the issue I am facing is to find all the pairs (x, y) for given number N in linear time (Obviously, we cannot loop through 10^50 to find all the pairs). Can someone suggest any approach, or any formula (if exists), to get all the pairs in linear time.
回答1:
You can create a 2-D array of size 451*451 and for all pair we can store whether it is prime or not. At the same time if you know how many numbers less than n who have F(x)=i and how many have F(x)=j, then after checking (i+j) is prime or not you can easily find a result with the state (i,j) of 2-D array of size 451*451.
So what you need is finding the total numbers who have F(x) =i.
You can easily do it using digit dp:
Digit DP for finding how many numbers who have F(x)=i:
string given=convertIntToString(given string);
int DP[51][2][452]= {-1};
Initially all index hpolds -1;
int digitDp(int pos,int small,int sum)
{
if(pos==given.size())
{
if(sum==i) return 1;
else return 0;
}
if(DP[pos][small][sum]!=-1)return DP[pos][small][sum];
int res=0;
if(small)
{
for(int j=0; j<=9; j++)res=(res+digitDp(pos+1,small,sum+j))%1000000007;
}
else
{
int hi=given[pos]-'0';
for(int j=0; j<=hi; j++)
{
if(j==hi)res=(res+digitDp(pos+1,small,sum+j))%1000000007;
else res=(res+digitDp(pos+1,1,sum+j))%1000000007;
}
}
return DP[pos][small][sum]=res;
}
This function will return the total numbers less than n who have F(x)=i.
So we can call this function for every i from 0 to 451 and can store the result in a temporary variable.
int res[452];
for(i=0;i<=451;i++){
memset(DP,-1,sizeof DP);
res[i]=digitDp(0,0,0);
}
Now test for each pair (i,j) :
int answer=0;
for(k=0;k<=451;k++){
for(int j=0;j<=451;j++){
if(isprime(k+j)){
answer=((log long)answer+(long long)res[k]*(long long)res[j])%1000000007;
}
}
}
finally result will be answer/2 as (i,j) and (j,i) will be calculated once.
Although there is a case for i=1 and j=1 , Hope you will be able to handle it.
来源:https://stackoverflow.com/questions/56737445/special-pairs-with-sum-as-prime-number