1. 程式人生 > >bzoj 3629

bzoj 3629

因子 def tdi n) lin 大於 include 指數 span

給出數 $n$
記 $f(x)$ 表示 $x$ 的因子和
求出所有 $x$ 使得 $f(x) = n$
考慮 $x = p_1 ^{a_1} * p_2 ^ {a_2} * \cdots * p_k ^ {a_k}$
那麽 $f(x) = (1 + p_1 + p_1 ^ 2 + \cdots + p_1 ^ {a_1}) * (1 + p_2 + p_2 ^ 2 + \cdots + p_2 ^ {a_2}) * \cdots * (1 + p_k + p_k
^ 2 + \cdots + p_k ^ {a_k})$
因此可以爆搜枚舉 $p, a$
Dfs(Now_result, prime_pos, x_remind) {}

分別表示
1.當前結果,即枚舉到的素數的指數次冪的乘積,即 $p_i ^ {a_i}$ 的乘積 
2.當前枚舉到的素數位置 首先要求出 $1e5, \sqrt(limit)$ 內的素數
3.給出的 $x$ 在枚舉了之前的數後還剩多少
對於答案的錄入
1.如果 x_remind = 1 ,相當於枚舉到了這樣一種形式 $() * () * () * p_i ^ 0$, 顯然當前 Now_result 可以錄入.
2.如果 x_remind - 1 是一個 大於等於 Prime[Prime_pos] 的素數,顯然 (x_remind - 1) * Now_result 可以錄入.
考慮這樣的話我們已經枚舉到了這樣的一種形式 $() * () * () * (p_i + 1)$, 所以還原之前的數就是 p_i * Now_result.

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>

using namespace std;

#define gc getchar()

inline int read() {
    int x = 0; char c = gc;
    while(c < 0 || c > 9) c = gc;
    while(c >= 0 && c <= 
9) x = x * 10 + c - 0, c = gc; return x; } const int N = 1e5 + 10; #define LL long long LL Prime[N], Mark[N], Ans_js; LL Answer[N], tot, n; void Get_prime() { for(int i = 2; i <= N - 5; i ++) { if(!Mark[i]) Prime[++ tot] = i; for(int j = 1; j <= tot && Prime[j] * i < N; j ++) { Mark[Prime[j] * i] = 1; if(i % Prime[j] == 0) break; } } } bool Is_prime(LL x) { if(x == 1) return 0; for(int i = 1; Prime[i] * Prime[i] <= x; i ++) { if(x % Prime[i] == 0) return 0; } return 1; } void Dfs(LL Now_result, int prime_pos, LL x_remind) { if(x_remind == 1) { Answer[++ Ans_js] = Now_result; return ; } if(x_remind - 1 >= Prime[prime_pos] && Is_prime(x_remind - 1)) { Answer[++ Ans_js] = (x_remind - 1) * Now_result; } for(int i = prime_pos; Prime[i] * Prime[i] <= x_remind; i ++) { for(LL tmp = Prime[i] + 1, imp = Prime[i]; tmp <= x_remind; imp *= Prime[i], tmp += imp) { if(x_remind % tmp == 0) Dfs(Now_result * imp, i + 1, x_remind / tmp); } } } int main() { Get_prime(); while(scanf("%lld", &n) == 1) { Ans_js = 0; Dfs(1, 1, n); sort(Answer + 1, Answer + Ans_js + 1); cout << Ans_js << "\n"; for(int i = 1; i < Ans_js; i ++) cout << Answer[i] << " "; if(Ans_js) cout << Answer[Ans_js] << "\n"; } return 0; }

bzoj 3629