zoukankan      html  css  js  c++  java
  • bzoj3643 Phi的反函数

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3643

    【题解】

    n = p1^a1*p2^a2*...*pm^am

    phi(n) = p1(p1-1)^(a1-1)*p2(p2-1)^(a2-1)*...*pm^(am-1)

    最多有10个不同的质因数就超过maxint了,这告诉我们可以搜索

    我们假设p1<p2<p3<...<pm

    那么我们处理出<sqrt(n)的质数,因为我们只会用到这些质数来搜(因为其他平方完就爆炸了)

    那么我们就暴力尝试是否被(pi-1)整除,是的话枚举因子个数,dfs下去即可

    注意特判如果我当前剩下了n,n+1是个质数,那么也可以是直接当前答案*(n+1)

    复杂度……我咋知道

    O(能过)

    # include <math.h>
    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 5e4 + 10;
    const int mod = 1e9+7;
    
    # define RG register
    # define ST static
    
    ll ans = 1e18;
    int n, F;
    bool isnp[M];
    int p[M/3], pn=0;
    
    inline bool isprime(int n) {
        for (int i=1, to = sqrt(n); p[i] <= to; ++i)
            if(n % p[i] == 0) return false;
        return true;
    }
    
    inline void dfs(int n, int lst, ll sum) {
        if(sum >= ans) return;
        if(n == 1) { ans = sum; return ; }
        if(n > F && isprime(n+1)) ans = min(ans, sum*(n+1));
        for (int i=lst+1; p[i]-1 <= F && p[i]-1 <= n; ++i) {
            if(n % (p[i]-1) == 0) {
                int t = n/(p[i]-1); ll res = sum * p[i];
                dfs(t, i, res);
                while(t % p[i] == 0) {
                    t /= p[i];
                    res *= p[i];
                    dfs(t, i, res);
                }
            }
        }
    }
    
    int main() {
        cin >> n;
        F = sqrt(n);
        isnp[0] = isnp[1] = 1;
        for (int i=2; i<=50000; ++i) {
            if(!isnp[i]) p[++pn] = i;
            for (int j=1; j<=pn && i*p[j] <= 50000; ++j) {
                isnp[i*p[j]] = 1;
                if(i%p[j] == 0) break;
            }
        }
        dfs(n, 0, 1);
        if(ans <= 2147483647) cout << ans << endl;
        else cout << -1 << endl;
        return 0;
    }
    View Code
  • 相关阅读:
    POJ 3114 Tarjan+Dijkstra
    278. First Bad Version
    209. Minimum Size Subarray Sum
    154. Find Minimum in Rotated Sorted Array II
    153. Find Minimum in Rotated Sorted Array
    710. Random Pick with Blacklist
    767. Reorganize String
    524. Longest Word in Dictionary through Deleting
    349. Intersection of Two Arrays
    350. Intersection of Two Arrays II
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj3643.html
Copyright © 2011-2022 走看看