uva 10837 - A Research Problem(欧拉函数+暴力)

题目链接:uva 10837 - A Research Problem

题目大意:给定一个phin,要求一个最小的n,欧拉函数n等于phin

解题思路:欧拉函数性质有,p为素数的话有phip=p?1;如果p和q互质的话有phip?q=phip?phiq

然后根据这样的性质,n=pk11(p1?1)?pk22(p2?1)???pkii(pi?1),将所有的pi处理出来,暴力搜索维护最小值,虽然看上去复杂度非常高,但是因为对于垒乘来说,增长非常快,所以搜索范围大大被缩小了。

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

using namespace std;
const int maxp = 1e4;
const int INF = 0x3f3f3f3f;

int ans;
int np, vis[maxp+5], pri[maxp+5];
int nf, fact[maxp+5], v[maxp+5];

void prime_table (int n) {
    np = 0;
    for (int i = 2; i <= n; i++) {
        if (vis[i])
            continue;

        pri[np++] = i;
        for (int j = i * i; j <= n; j += i)
            vis[j] = 1;
    }
}

void get_fact (int n) {
    nf = 0;

    for (int i = 0; i < np && (pri[i]-1) * (pri[i]-1) <= n; i++) {
        if (n % (pri[i]-1) == 0)
            fact[nf++] = pri[i];
    }
}

bool judge (int n) {
    if (n == 2)
        return true;
    for (int i = 0; i < np && pri[i] * pri[i] <= n; i++)
        if (n % pri[i] == 0)
            return false;

    for (int i = 0; i < nf; i++)
        if (v[i] && fact[i] == n)
            return false;
    return true;
}

void dfs (int ret, int cur, int d) {
    if (d == nf) {
        if (judge(cur+1)) {

            if (cur == 1)
                cur = 0;

            ans = min(ans, ret * (cur+1));
        }
        return;
    }

    dfs(ret, cur, d+1);
    if (cur % (fact[d]-1) == 0) {
        v[d] = 1;
        ret *= fact[d];
        cur /= (fact[d]-1);

        while (true) {
            dfs(ret, cur, d+1);

            if (cur % fact[d])
                return;
            ret *= fact[d];
            cur /= fact[d];
        }
        v[d] = 0;
    }
}

int solve (int n) {
    ans = INF;
    get_fact(n);
    memset(v, 0, sizeof(v));
    dfs(1, n, 0);
    return ans;
}

int main () {
    prime_table(maxp);
    int cas = 1, n;
    while (scanf("%d", &n) == 1 && n) {
        printf("Case %d: %d %d\n", cas++, n, solve(n));
    }
    return 0;
}

uva 10837 - A Research Problem(欧拉函数+暴力),布布扣,bubuko.com

时间: 2024-08-23 21:21:37

uva 10837 - A Research Problem(欧拉函数+暴力)的相关文章

UVA 10837 - A Research Problem(欧拉函数)

UVA 10837 - A Research Problem 题目链接 题意:给定phi(n),求最小满足的最小的n 思路:phi(n)=pk11(p1?1)?pk22(p2?1)?pk33(p3?1)....(p为质数),因此对于给定phi(n),先把满足条件phi(n)%(p?1)=0的素数全找出来,在这些素数基础上进行暴力搜索,枚举哪些素数用与不用,求出最小值.这样做看似时间复杂度很高,但是实际上,由于每次多选一个素数之后对于值是呈指数上升的,所以实际组合出来的情况并不会太多,因此是可行的

uva 10837 - A Research Problem(欧拉功能+暴力)

题目链接:uva 10837 - A Research Problem 题目大意:给定一个phin.要求一个最小的n.欧拉函数n等于phin 解题思路:欧拉函数性质有,p为素数的话有phip=p?1;假设p和q互质的话有phip?q=phip?phiq 然后依据这种性质,n=pk11(p1?1)?pk22(p2?1)???pkii(pi?1),将全部的pi处理出来.暴力搜索维护最小值,尽管看上去复杂度很高,可是由于对于垒乘来说,增长很快,所以搜索范围大大被缩小了. #include <cstdi

POJ2480 Longge&#39;s problem 欧拉函数的应用 &amp;&amp; 积性函数

题意很简单,求sum(gcd(i,n))   1<=i<=n; 这题看到后第一反应并没有里用积性函数的性质,不过也可以做,欣慰的是我反应还是比较快的 设f(n)=gcd(1,n)+gcd(2,n)+....+gcd(n-1,n) + gcd(n,n), 用g(n,i)表示满足 gcd(x,n)=i的 x的个数 (x小于n),则 f(n)=sum{i*g(n,i)}; 同时又利用 扩展欧几里德的性质  gcd(x,n)=i  的充要条件是 gcd(x/i,n/i)==1,所以 满足 x/i的解有

poj 2480 Longge&#39;s problem [ 欧拉函数 ]

传送门 Longge's problem Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7327   Accepted: 2416 Description Longge is good at mathematics and he likes to think about hard mathematical problems which will be solved by some graceful algorithms.

UVA 11426 - GCD - Extreme (II) 欧拉函数-数学

Given the value of N, you will have to ?nd the value of G. The de?nition of G is given below:G =i<N∑i=1j∑≤Nj=i+1GCD(i, j)Here GCD(i, j) means the greatest common divisor of integer i and integer j.For those who have trouble understanding summation no

UVa 10820 (打表、欧拉函数) Send a Table

题意: 题目背景略去,将这道题很容易转化为,给出n求,n以内的有序数对(x, y)互素的对数. 分析: 问题还可以继续转化. 根据对称性,我们可以假设x<y,当x=y时,满足条件的只有(1, 1). 设f(n)为 集合S{(x, y) | x<y且x.y互素} 的个数,则所求答案为2f(n)+1 f(n)表达式为: ,其中φ(n)为欧拉函数 这里有欧拉函数的一些介绍 1 #include <cstdio> 2 3 const int maxn = 50000; 4 5 int ph

Uva 10820 Send a Table(欧拉函数)

对每个n,答案就是(phi[2]+phi[3]+...+phi[n])*2+1,简单的欧拉函数应用. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<map> #include<set> #include<list> #i

UVA 11426 GCD - Extreme (II) 欧拉函数

分析:枚举每个数的贡献,欧拉函数筛法 #include <cstdio> #include <iostream> #include <ctime> #include <vector> #include <cmath> #include <map> #include <queue> #include <algorithm> #include <cstring> using namespace std;

UVa 10214 (莫比乌斯反演 or 欧拉函数) Trees in a Wood.

题意: 这道题和POJ 3090很相似,求|x|≤a,|y|≤b 中站在原点可见的整点的个数K,所有的整点个数为N(除去原点),求K/N 分析: 坐标轴上有四个可见的点,因为每个象限可见的点数都是一样的,所以我们只要求出第一象限可见的点数然后×4+4,即是K. 可见的点满足gcd(x, y) = 1,于是将问题转化为x∈[1, a], y∈[1, b],求gcd(x, y) = 1的个数. 类比HDU 1695可以用莫比乌斯反演来做,我还写了普通的和分块加速的两份代码,交上去发现运行时间相差并不