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
  • 相关阅读:
    Single Number II
    Pascal's Triangle
    Remove Duplicates from Sorted Array
    Populating Next Right Pointers in Each Node
    Minimum Depth of Binary Tree
    Unique Paths
    Sort Colors
    Swap Nodes in Pairs
    Merge Two Sorted Lists
    Climbing Stairs
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj3643.html
Copyright © 2011-2022 走看看