Original link https://www.cnblogs.com/zhouzhendong/p/CF542D.html
Question portal-cf542d question portal-51nod1477
Define the formula $ J (x) = \ sum _ {1 \ Leq k \ Leq X and k | X and \ gcd (K, X/K) = 1} k $.
Given an integer $ A $, the number of positive integers $ x $ must be equal to $ J (x) = A $.
$ X | N $ indicates that $ x $ is a factor of $ N $.
$ \ Gcd (a, B) indicates the maximum common divisor of $ A $ and $ B $.
$1 \ Leq A \ Leq 10 ^ {12} $
Question
Consider how to calculate $ J (x) $ first.
Because $ \ gcd (K, X/K) = 1 $, the selected prime factor set of $ x $ and $ X/K $ has no intersection.
Therefore, if you set $ x = \ prod p_ I ^ {a_ I} $, then $ J (x) = \ prod (p_ I ^ {a_ I} + 1) $.
So we considered the factorization method of DFS enumerative A, and added some pruning and optimization.
Code
#include <bits/stdc++.h>using namespace std;typedef long long LL;LL read(){LL x=0;char ch=getchar();while (!isdigit(ch))ch=getchar();while (isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();return x;}const int N=1000005;LL n;struct hash_map{ static const int Ti=233,mod=1<<21; int cnt,nxt[mod+1],fst[mod+1]; LL k[mod+1],v[mod+1]; int Hash(LL x){ int v=x&(mod-1); return v==0?mod:v; } void clear(){ cnt=0; memset(fst,0,sizeof fst); } LL &operator [] (LL x){ int y=Hash(x); for (int p=fst[y];p;p=nxt[p]) if (k[p]==x) return v[p]; k[++cnt]=x,nxt[cnt]=fst[y],fst[y]=cnt; return v[cnt]=0; }}check,use;LL prime[N],pcnt,vis[N];void get_prime(){memset(vis,0,sizeof vis);pcnt=0;for (int i=2;i<N;i++){if (vis[i])continue;prime[++pcnt]=i;for (int j=i+i;j<N;j+=i)vis[j]=1;}}int Check(LL x){if (x<=1)return 0;for (int i=1;prime[i]*prime[i]<=x&&i<=pcnt;i++)if (x%prime[i]==0){while (x%prime[i]==0)x/=prime[i];return x==1?prime[i]:0;}return x;}LL ans=0;LL fac[N*2],fc=0;void dfs(LL n,LL *d){if (*d>n)return;if (check[n]&&!use[check[n]])ans++;if (*d>=n/ *d)return;for (;*d<n/ *d;d++){if (n%*d)continue;LL &v=use[check[*d]];if (!v)v=1,dfs(n/ *d,d+1),v=0;}}int main(){get_prime();n=read();if (n==1)return puts("1"),0;check.clear();for (LL i=1;i*i<=n;i++){if (n%i)continue;LL j=n/i;check[i]=Check(i-1);check[j]=Check(j-1);if (check[i])fac[fc++]=i;if (i!=j&&check[j])fac[fc++]=j;}use.clear();sort(fac,fac+fc);fac[fc]=n+1;dfs(n,fac);printf("%lld",ans);return 0;}
Codeforces 542d superhero's job number theory hash table search