[CF542D]Superhero's Job

[CF542D]Superhero's Job

题目大意:

定义函数

[J(x) = sum_{substack{1 leq k leq x \ k mid x \ gcd left( k, x / k ight) = 1}} k ]

给定(n(nle10^{12})),求方程(J(x)=n)的解的个数。

思路:

对于(gcd(a,b)=1)(J(ab)=J(a)J(b))

对于(pinmathbb{P})(J(p^k)=p^k+1)

(10^{12})内,约数最多的数( au(963761198400)=6720)

DP:(f[i])表示组成第(i)种有用的约数的方案数。

源代码:

#include<map>
#include<cstdio>
#include<cctype>
#include<vector>
#include<algorithm>
typedef long long int64;
inline int64 getint() {
	register char ch;
	while(!isdigit(ch=getchar()));
	register int64 x=ch^'0';
	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
	return x;
}
const int D=6721;
std::vector<int64> p;
std::map<int64,int> map;
int64 d[D],f[D];
int main() {
	const int64 n=getint();
	for(register int64 i=1;i*i<=n;i++) {
		if(n%i) continue;
		d[++d[0]]=i;
		if(i*i!=n) d[++d[0]]=n/i;
	}
	std::sort(&d[1],&d[d[0]]+1);
	for(register int i=1;i<=d[0];i++) {
		map[d[i]]=i;
		int64 x=d[i]-1;
		for(register int64 j=2;j*j<=x;j++) {
			if(x%j) continue;
			while(x%j==0) x/=j;
			if(x==1) p.push_back(j);
		}
		if(x>1) p.push_back(x);
	}
	std::sort(p.begin(),p.end());
	p.resize(std::unique(p.begin(),p.end())-p.begin());
	const int m=p.size();
	f[1]=1;
	for(register int i=0;i<m;i++) {
		for(register int j=d[0];j;j--) {
			int64 t=p[i];
			while(t<d[j]) {
				if(d[j]%(t+1)==0) {
					f[j]+=f[map[d[j]/(t+1)]];
				}
				t*=p[i];
			}
		}
	}
	printf("%lld
",f[d[0]]);
	return 0;
}
原文地址:https://www.cnblogs.com/skylee03/p/10219415.html