题目链接:http://www.spoj.com/problems/AMR10I/
题目大意:把一个数N(N<70),分成几个数和的形式,再把这几个数相乘,问有多少种不同的乘积(种数对p取模)?
样例:
CONSTRAINTS
T <= 20
2 <= N <= 70
2 <= P <= 1e9
SAMPLE INPUT
2
3 1000
5 1000
SAMPLE OUTPUT
3
6
EXPLANATION
In the first test case, the possible ways of division are (1,1,1), (1,2), (2,1) and (3) which have values 1, 2, 2, 3 and hence, there are 3 distinct values.
In the second test case, the numbers 1 to 6 constitute the answer and they can be obtained in the following ways:
1=1*1*1*1*1
2=2*1*1*1
3=3*1*1
4=4*1
5=5
6=2*3
解题思路:因为任何一个数都可以分成若干个素数的乘积(1除外);那么只需要深搜枚举70以内的素数乘积即可,同时维护和为 N。其中用set容器去重。
代码如下:
#include<stdio.h>
#include<set>
#include<algorithm>
using namespace std;
int n,p;
set<long long> S;
int pr[]={2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73};
void dfs(int x,int n,long long ji)
{
S.insert(ji);
if(pr[x]>n) return;
dfs(x,n-pr[x],ji*pr[x]%p);//取第x个素数
dfs(x+1,n,ji);//从第x+1个素数深搜
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
S.clear();
scanf("%d%d",&n,&p);
dfs(0,n,1);
printf("%d\n",S.size());
}
return 0;
}