ACM学习历程—HDU1719 Friend(数论)

Description

Friend number are defined recursively as follows.
(1) numbers 1 and 2 are friend number;

(2) if a and b are friend numbers, so is ab+a+b;

(3) only the numbers defined in (1) and (2) are friend number.

Now your task is to judge whether an integer is a friend number.

Input

There are several lines in input, each line has a nunnegative integer a, 0<=a<=2^30.

Output

For the number a on each line of the input, if a is a friend number, output “YES!”, otherwise output “NO!”.

Sample Input

3

13121

12131

Sample Output

YES!

YES!

NO!

由题意,如果n = a+b+ab,a和b都是friend number

那么(n+1) = (a+1) * (b+1),

然后我记friend number叫做好数。

那么2和3是好数。

然后两个好数相乘也是好数。

由于其他数首先都是由2和3生出的,所以好数必然是2^k * 3^p。

接下来证明所有2^k * 3^p都是好数。

反证:

若2^k * 3^p不是好数,那么2^(k-1) * 3^p必然也不是好数,否则2^(k-1) * 3^p和2相乘会导致2^k * 3^p也是好数。

然后递降下来说明了3^p也不是好数。

同理说明了3不是好数。

矛盾!

所以所有2^k * 3^p都是好数。

于是判断好数只需要先把二因子除去,这里采用位运算优化。

然后除去3因子,判断最后结果是不是1。这里打表保存了3的所有指数密进行判断。

能判断好数了,自然能判断friend number了。不过需要对0进行特判。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#define LL long long

using namespace std;

const int maxn = 1<<30;

set <LL> s;

void Init()
{
    int now = 2;
    s.insert(1);
    for (;;)
    {
        if (now > maxn)
            break;
        s.insert(now);
        now = 2*now + 1;
    }
    now = 5;
    for (;;)
    {
        if (now > maxn)
            break;
        s.insert(now);
        now = 3*now + 2;
    }

    now = 11;
    for (;;)
    {
        if (now > maxn)
            break;
        s.insert(now);
        now = 6*now + 5;
    }
}

bool judge(LL n)
{
    if (no.find(n) != no.end())
        return false;
    if (s.find(n) != s.end())
        return true;
    n++;
    int len = sqrt(n);
    for (int i = 2; i <= len; ++i)
    {
        if (n % i)
            continue;
        if (judge(i-1)&&judge(n/i-1))
        {
            s.insert(n);
            return true;
        }
    }
    no.insert(n);
    return false;
}

int main()
{
    //freopen("test.in", "r", stdin);
    LL n;
    Init();
    while (scanf("%I64d", &n) != EOF)
    {
        if (judge(n))
            printf("YES!\n");
        else
            printf("NO!\n");
    }
    return 0;
}
时间: 2024-10-10 05:03:39

ACM学习历程—HDU1719 Friend(数论)的相关文章

ACM学习历程—HDU 4726 Kia&#39;s Calculation( 贪心&amp;&amp;计数排序)

DescriptionDoctor Ghee is teaching Kia how to calculate the sum of two integers. But Kia is so careless and alway forget to carry a number when the sum of two digits exceeds 9. For example, when she calculates 4567+5789, she will get 9246, and for 12

ACM学习历程—HDU 5023 A Corrupt Mayor&#39;s Performance Art(广州赛区网赛)(线段树)

Problem Description Corrupt governors always find ways to get dirty money. Paint something, then sell the worthless painting at a high price to someone who wants to bribe him/her on an auction, this seemed a safe way for mayor X to make money. Becaus

ACM学习历程—UESTC 1226 Huatuo&#39;s Medicine(数学)(2015CCPC L)

题目链接:http://acm.uestc.edu.cn/#/problem/show/1226 题目就是构造一个对称的串,除了中间的那个只有1个,其余的两边都是对称的两个,自然答案就是2*n-1. 代码: #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <algorithm> #

ACM学习历程—HDU5585 Numbers(数论 || 大数)(BestCoder Round #64 (div.2) 1001)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5585 题目大意就是求大数是否能被2,3,5整除. 我直接上了Java大数,不过可以对末尾来判断2和5,对所有位的和来判断3. 代码就不粘了.

ACM学习历程—HDU5668 Circle(数论)

http://acm.hdu.edu.cn/showproblem.php?pid=5668 这题的话,假设每次报x个,那么可以模拟一遍, 假设第i个出局的是a[i],那么从第i-1个出局的人后,重新报数到他假设经过了p个人, 那么自然x = k(n-i)+p(0<= i < n) 即x = p (mod n-i) 然后显然可以得到n个这样的方程,于是就是中国剩余定理了. 代码: #include <iostream> #include <cstdio> #includ

ACM学习历程—广东工业大学2016校赛决赛-网络赛F 我是好人4(数论)

题目链接:http://gdutcode.sinaapp.com/problem.php?cid=1031&pid=5 这个题目一看就是一道数论题,应该考虑使用容斥原理,这里对lcm进行容斥. 不过直接上去是T,考虑到序列中同时存在i和ki的话,其实只需要考虑i,所以先对序列中为倍数的对进行处理. 这里的容斥用了hqw的写法. 代码: #include <iostream> #include <cstdio> #include <cstdlib> #includ

ACM学习历程—HDU5637 Transform(数论 &amp;&amp; 最短路)

题目链接:http://codeforces.com/problemset/problem/590/A 题目大意是给两种操作,然后给你一个s,一个t,求s至少需要多少次操作到t. 考虑到第一种操作是将某一位取反,而第二种操作是抑或一个数. 显然第一种操作也是可以通过抑或一个数得到的.比如:第i位取反,相当于抑或(1<<i)这个数.于是就将n个数扩大到n+17就可以了,因为100000最多17位. 此外如果p^a^b^c...=q的话,那么a^b^c...=p^q.于是,只需要求出p^q至少需要

ACM学习历程—SNNUOJ1132 余数之和(数论)

Description F(n) = (n % 1) + (n % 2) + (n % 3) + ...... (n % n).其中%表示Mod,也就是余数.例如F(6) = 6 % 1 + 6 % 2 + 6 % 3 + 6 % 4 + 6 % 5 + 6 % 6 = 0 + 0 + 0 + 2 + 1 + 0 = 3.给出n,计算F(n). Input 输入1个数N(2 <= N <= 10^12). Output 输出F(n). Sample Input 6 Sample Output

ACM学习历程—HDU 3092 Least common multiple(数论 &amp;&amp; 动态规划 &amp;&amp; 大数)

hihoCoder挑战赛12 Description Partychen like to do mathematical problems. One day, when he was doing on a least common multiple(LCM) problem, he suddenly thought of a very interesting question: if given a number of S, and we divided S into some numbers