• LOJ #2234. 「JLOI2014」聪明的燕姿(搜索 + 数论)


    题意

    给出一个数 (S) ,输出所有约数和等于 (S) 的数。

    (S le 2 imes 10^9) ,数据组数 (le 100)

    题解

    首先用约数和定理:

    [egin{align} n &= prod_{i} p_i^{a_i} \ Rightarrow sigma(n) &= prod_{i} (sum_{j=0}^{a_i} p_i^j) end{align} ]

    那么,我们可以通过从小到大来枚举质数 (p_i) 及其指数 (a_i) 来搜索。

    • 若当前需要得到的 (S) 可以表示为一个未搜索过的质数与 (1) 的和,那么之前的数与这个质数的乘积是一个合法答案。

    • 对于每一个使得 ((p + 1) imes (p + 1) < S)(p) ,枚举可能的 (a_i) ,递归。

      因为在第一种情况会把 (a_i = 1) 的特判掉(这种数出现并且仅出现一次),然后剩下的 (a_i ge 2) ,所以至少为 (1 + p + p ^ 2)

    最后当一直除到 (1) 的时候就是答案了qwq

    最开始随便用筛法筛素数就行了,复杂度 (O(pass)) 。。。

    总结

    对于约数和之类的题,考虑对于 (a_i = 1)(a_i ge 2) 的情况分别考虑就行了,前者只存在一个,后者 (le sqrt p)

    代码

    随便看看实现就行了。。跑的速度还行qwq

    #include <bits/stdc++.h>
    
    #define For(i, l, r) for(register int i = (l), i##end = (int)(r); i <= i##end; ++i)
    #define Fordown(i, r, l) for(register int i = (r), i##end = (int)(l); i >= i##end; --i)
    #define Set(a, v) memset(a, v, sizeof(a))
    #define Cpy(a, b) memcpy(a, b, sizeof(a))
    #define debug(x) cout << #x << ": " << (x) << endl
    #define DEBUG(...) fprintf(stderr, __VA_ARGS__)
    #define mp make_pair
    
    using namespace std;
    
    template<typename T> inline bool chkmin(T &a, T b) {return b < a ? a = b, 1 : 0;}
    template<typename T> inline bool chkmax(T &a, T b) {return b > a ? a = b, 1 : 0;}
    
    inline int read() {
        int x(0), sgn(1); char ch(getchar());
        for (; !isdigit(ch); ch = getchar()) if (ch == '-') sgn = -1;
        for (; isdigit(ch); ch = getchar()) x = (x * 10) + (ch ^ 48);
        return x * sgn;
    }
    
    void File() {
    #ifdef zjp_shadow
    	freopen ("2234.in", "r", stdin);
    	freopen ("2234.out", "w", stdout);
    #endif
    }
    
    set<int> S;
    
    const int Maxn = sqrt(2e9);
    bitset<Maxn + 5> is_prime;
    
    void Math_Init(int maxn) {
    	is_prime.set();
    	is_prime[0] = is_prime[1] = false;
    	For (i, 2, maxn) if (is_prime[i])
    		for (int j = i * 2; j <= maxn; j += i) is_prime[j] = false;
    }
    
    inline bool Judge(int x) {
    	if (x <= Maxn) return is_prime[x];
    	for (int i = 2; i * i <= x; ++ i)
    		if (!(x % i)) return false;
    	return true;
    }
    
    void Dfs(int x, int cur, int pre) {
    	if (x == 1) { S.insert(cur); return ; }
    	if (x - 1 > pre && Judge(x - 1))
    		S.insert(cur * (x - 1));
    
    	For (p, pre + 1, sqrt(x + .5))
    		if (is_prime[p]) {
    			int sum = p + 1, here = p;
    			while (sum <= x) {
    				if (!(x % sum))
    					Dfs(x / sum, cur * here, p);
    				here *= p; sum += here;
    			}
    		}
    }
    
    int main () {
    
    	File();
    
    	Math_Init(Maxn);
    
    	int x;
    	while (~scanf("%d", &x)) {
    		S.clear(); Dfs(x, 1, 1);
    		printf ("%d
    ", (int)S.size());
    		for (int cur : S) printf ("%d ", cur); 
    		if ((bool)S.size()) putchar ('
    ');
    	}
    
    	return 0;
    
    }
    
  • 相关阅读:
    第一周任务Largest Submatrix of All 1’s
    第一周 Largest Rectangle in a Histogram
    第二次作业
    B. Light bulbs(2019 ICPC上海站)
    二维平面最近点-分治
    python生成器,推导式
    python函数名的运用,闭包,迭代器
    python函数(二)
    python函数(一)
    python基础(七)
  • 原文地址:https://www.cnblogs.com/zjp-shadow/p/9761316.html
Copyright © 2020-2023  润新知