大菜鸡的数论之旅-[kuangbin带你飞]专题十四 数论基础

大菜鸡的数论之旅-[kuangbin带你飞]专题十四 数论基础

A题 LightOJ 1370 Bi-shoe and Phi-shoe

Problem Description

Bamboo Pole-vault is a massively popular sport in Xzhiland. And Master Phi-shoe is a very popular coach for his success. He needs some bamboos for his students, so he asked his assistant Bi-Shoe to go to the market and buy them. Plenty of Bamboos of all possible integer lengths (yes!) are available in the market. According to Xzhila tradition,Score of a bamboo = Φ (bamboo’s length)
(Xzhilans are really fond of number theory). For your information, Φ (n) = numbers less than n which are relatively prime (having no common divisor other than 1) to n. So, score of a bamboo of length 9 is 6 as 1, 2, 4, 5, 7, 8 are relatively prime to 9.
The assistant Bi-shoe has to buy one bamboo for each student. As a twist, each pole-vault student of Phi-shoe has a lucky number. Bi-shoe wants to buy bamboos such that each of them gets a bamboo with a score greater than or equal to his/her lucky number. Bi-shoe wants to minimize the total amount of money spent for buying the bamboos. One unit of bamboo costs 1 Xukha. Help him.

Input

Input starts with an integer T (≤ 100), denoting the number of test cases.
Each case starts with a line containing an integer n (1 ≤ n ≤ 10000) denoting the number of students of Phi-shoe. The next line contains n space separated integers denoting the lucky numbers for the students. Each lucky number will lie in the range [1, 106].

Output

For each case, print the case number and the minimum possible money spent for buying the bamboos. See the samples for details.

Sample Input

3
5
1 2 3 4 5
6
10 11 12 13 14 15
2
1 1

Sample Output

Case 1: 22 Xukha
Case 2: 88 Xukha
Case 3: 4 Xukha

----------------------------------------------------分割线-----------------------------------------------------------------------

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N=1e6+5;

int num[10005];
int pr[N],phi[N];
bool f[N];

void init()
{
    int i,j,k,p=0;
    phi[1]=1;
    for(i=2; i<N; ++i)
    {
        if(!f[i])
            phi[pr[++p]=i]=i-1;
        for(j=1; j<=p&&(k=i*pr[j])<N; ++j)
        {
            f[k]=1;
            if(i%pr[j])
                phi[k]=phi[i]*(pr[j]-1);
            else
            {
                phi[k]=phi[i]*pr[j];
                break;
            }
        }
    }
}

int main()
{
    init();
    int T;
    scanf("%d",&T);
    for(int cas=1;cas<=T;cas++)
    {
        int n;
        scanf("%d",&n);
        ll ans=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&num[i]);
            for(int j=max(num[i],2);j<N;j++)
            {
                if(phi[j]>=num[i])
                {
                    ans+=j;
                    break;
                }
            }
        }
        printf("Case %d: %lld Xukha\n",cas,ans);
    }
    return 0;
}


B题不见了~


C题 LightOJ 1341 Aladdin and the Flying Carpet

Problem Description

It’s said that Aladdin had to solve seven mysteries before getting the Magical Lamp which summons a powerful Genie. Here we are concerned about the first mystery.
Aladdin was about to enter to a magical cave, led by the evil sorcerer who disguised himself as Aladdin’s uncle, found a strange magical flying carpet at the entrance. There were some strange creatures guarding the entrance of the cave. Aladdin could run, but he knew that there was a high chance of getting caught. So, he decided to use the magical flying carpet. The carpet was rectangular shaped, but not square shaped. Aladdin took the carpet and with the help of it he passed the entrance.
Now you are given the area of the carpet and the length of the minimum possible side of the carpet, your task is to find how many types of carpets are possible. For example, the area of the carpet 12, and the minimum possible side of the carpet is 2, then there can be two types of carpets and their sides are: {2, 6} and {3, 4}.

Input

Input starts with an integer T (≤ 4000), denoting the number of test cases.
Each case starts with a line containing two integers: a b (1 ≤ b ≤ a ≤ 1012) where a denotes the area of the carpet and b denotes the minimum possible side of the carpet.

Output

For each case, print the case number and the number of possible carpets.

Sample Input

2
10 2
12 2

Sample output

Case 1: 1
Case 2: 2


代码

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6+7;

typedef long long ll;

#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)

bool vis[N];
int prime[N];
int cnt;

void sieve(ll n)
{
    int m=(int)sqrt(n+0.5);
    memset(vis,0,sizeof(vis));
    rep(i,2,m)
    {
        if(!vis[i])
        {
            for (int j=i*i; j<=n; j+=i)
                vis[j]=1;
        }
    }
}

int gen_primes(int n)
{
    sieve(n);
    int c=0;
    for(int i=1; i<=n; i++)
        if(!vis[i])
            prime[c++]=i;
    return c;
}

int main()
{
    cnt=gen_primes(N-1);
    int T,kase=0;
    scanf("%d",&T);

    while(T--)
    {
        ll a, b;
        scanf("%lld%lld",&a,&b);
        ll ans=1;
        if(b>=sqrt(a))
        {
            printf("Case %d: %d\n",++kase,0);
            continue;
        }
        else
        {
            ll tmp=a;
            for (int i=1;i<cnt&&1ll*prime[i]*prime[i]<=a;i++)
            {
                if (a%prime[i]==0)
                {
                    int num=0;
                    while(a%prime[i]==0)
                    {
                        num++;
                        a/=prime[i];
                    }
                    ans*=(num+1);
                }
            }
            if(a>1)
                ans*=2;
            ans/=2;
            for(int i=1;i<b;i++)
                if (tmp%i==0)
                    ans--;
        }
        printf("Case %d: %lld\n",++kase,ans);
    }
    return 0;
}


D题 LightOJ 1336 Sigma Function

Problem Description

Sigma function is an interesting function in Number Theory. It is denoted by the Greek letter Sigma (σ). This function actually denotes the sum of all divisors of a number. For example σ(24) = 1+2+3+4+6+8+12+24=60. Sigma of small numbers is easy to find but for large numbers it is very difficult to find in a straight forward way. But mathematicians have discovered a formula to find sigma. If the prime power decomposition of an integer is
在这里插入图片描述
Then we can write,
在这里插入图片描述
For some n the value of σ(n) is odd and for others it is even. Given a value n, you will have to find how many integers from 1 to n have even value of σ.

Input

Input starts with an integer T (≤ 100), denoting the number of test cases.
Each case starts with a line containing an integer n (1 ≤ n ≤ 1012).

Output

For each case, print the case number and the result.


代码

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)

const int N=10005;

int main()
{
    int T;
    scanf("%d",&T);
    rep(cas,1,T)
    {
        ll n;
        scanf("%lld",&n);
        printf("Case %d: %lld\n",cas,n-(int)sqrt(n)-(int)sqrt(n/2));
    }
    return 0;
}


E题 LightOJ 1282 Leading and Trailing

Problem Description

You are given two integers: n and k, your task is to find the most significant three digits, and least significant three digits of nk.

Input

Input starts with an integer T (≤ 1000), denoting the number of test cases.
Each case starts with a line containing two integers: n (2 ≤ n < 231) and k (1 ≤ k ≤ 107).

Output

For each case, print the case number and the three leading digits (most significant) and three trailing digits (least significant). You can assume that the input is given such that nk contains at least six digits.

Sample Input

5
123456 1
123456 2
2 31
2 32
29 8751919

Sample Output

Case 1: 123 456
Case 2: 152 936
Case 3: 214 648
Case 4: 429 296
Case 5: 665 669


代码

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)

ll quick_pow(ll a, ll b, ll p)
{
    ll ans=1;
    a%=p;
    while(b)
    {
        if(b&1) ans=ans*a%p;
        a=a*a%p;
        b>>=1;
    }
    return ans;
}

ll cal(ll n,ll k,int dig)
{
    return pow(10.0,dig+fmod((double)k*log10((double)n),1));
}

int main()
{
    int T;
    scanf( "%d",&T);
    rep(cas,1,T)
    {
        int n,k;
        scanf("%d%d",&n,&k);
        printf("Case %d: %lld %03lld\n",cas,cal(n,k,2),quick_pow(n,k,1000));
    }
    return 0;
}


F题 LightOJ 1259 Goldbach`s Conjecture

Problem Description

Goldbach’s conjecture is one of the oldest unsolved problems in number theory and in all of mathematics. It states:
Every even integer, greater than 2, can be expressed as the sum of two primes [1].
Now your task is to check whether this conjecture holds for integers up to 107.

Input

Input starts with an integer T (≤ 300), denoting the number of test cases.
Each case starts with a line containing an integer n (4 ≤ n ≤ 107, n is even).

Output

For each case, print the case number and the number of ways you can express n as sum of two primes. To be more specific, we want to find the number of (a, b) where

  1.  Both a and b are prime
    
  2.  a + b = n
    
  3.  a ≤ b
    

Sample Input

2
6
4

Sample Output

Case 1: 1
Case 2: 1

Note

An integer is said to be prime, if it is divisible by exactly two different integers. First few primes are 2, 3, 5, 7, 11, 13, …


代码

#include <bits/stdc++.h>

#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)

using namespace std;

typedef long long ll;

const int N=1e6+5;
const int MAXN=1e7+5;

int pre[N];
bool check[MAXN];
int tot=0;

void init()
{
    memset(check,0,sizeof(check));
    for(int i=2; i<=MAXN; i++)
    {
        if(!check[i])
            pre[tot++]=i;
        for(int j=0; j<tot&&pre[j]*i<=MAXN; ++j)
        {
            check[i*pre[j]]=1;
            if(i%pre[j]==0)
                break;
        }
    }
}

int main()
{
    init();
    int T;
    scanf("%d",&T);
    rep(cas,1,T)
    {
        int n;
        scanf("%d",&n);
        int cnt=0;
        int ans=0;
        while(pre[cnt]<=n/2&&cnt<tot)
        {
            if(check[n-pre[cnt]]==false)
            {
                ans++;
            }
            cnt++;
        }
        printf("Case %d: %d\n",cas,ans);
    }
    return 0;
}

----------------------------------------分割线-----------------------------------------------------------------------------------

持续更新中~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值