 /**//*
给出n,问满足phi(k) = n的k的个数,其中k的素因子个数<=3 n<2^31
欧拉函数
phi(k) = k(1-1/p1)(1-1/p2)(1-1/p3)
= (p1-1)p1^x*(p2-1)p2^y*(p3-1)p3^z
phi(1) = 1

比赛时打算筛素数(筛到sqrt(2^31)),枚举p1,p2,p3
有问题的,比如 n = (3-1) * p
当n很大时,这样p就是一个很大的数了,而素数表没有,就枚举不到了!

问了ACOrz,他的代码很神奇呀
因为n = (p1-1)p1^x*(p2-1)p2^y*(p3-1)p3^z
用sqrt(n)枚举(pi-1)
if(n%(pi-1) && isPrime(pi))加入pi
然后就dfs出最多3个数,让 (p1-1)p1^x*(p2-1)p2^y*(p3-1)p3^z = n
注意的是phi(1) = 1
所以n=1时,满足条件的有2个,即k=1,2
ACOrz的代码很简洁,下面是我按照我的风格模仿他写的
注意枚举的是(pi - 1),不是n的素因子 !!!
*/
#include<iostream>
#include<cstring>
#include<map>
#include<algorithm>
#include<stack>
#include<queue>
#include<cmath>
#include<string>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<set>
#include<list>
#include<numeric>
#include<cassert>
#include<ctime>

using namespace std;

vector<int> prime;
int ans;

 bool isPrime(int n) {
 for(int p = 2; p <= n/p ; p++) {
 if(n % p == 0) {
return false;
}
}
return true;
}

 void dfs(int next, vector<int> with, int n) {
int nn = n;
bool can = true;
 for(vector<int>::iterator it = with.begin() ; it != with.end() ; it++) {//检查合法性
 if(n % (*it-1) == 0) {
n /= (*it-1);
 }else {
can = false;
break;
}
}
 if(can) {
//with可以为空!!!
 for(vector<int>::iterator it = with.begin() ; it != with.end() ; it++) {
 while(n % *it == 0) {
n /= *it;
}
}
if(n == 1)ans++;//特殊情况是with为空,但原始的n为1
 if(with.size() == 3) {
return;
}
 for(int i = next ; i < prime.size(); i++) {//扩展
with.push_back(prime[i]);
dfs(i+1, with, nn);
with.pop_back();
}
}
}

int main()
  {
#ifndef ONLINE_JUDGE
//freopen("in","r",stdin);
#endif

 for(int n; ~scanf("%d", &n); ) {
prime.clear();
 for(int i = 1 ; i <= n / i; i++) {
 if(n % i == 0) {
 if(isPrime(i+1)) {
prime.push_back(i+1);
}
 if(n/i != i && isPrime(n/i+1)) {
prime.push_back(n/i+1);
}
}
}
ans = 0;
dfs(0, vector<int>(), n);
printf("%d\n", ans);
}
return 0;
}
|
|
常用链接
随笔分类
Links
搜索
最新评论

|
|