1. 程式人生 > >永遠不可能學會的數論之基礎數論(例題)

永遠不可能學會的數論之基礎數論(例題)

涉及到知識

                                         Bi-shoe and Phi-shoe

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 

 Sample Output

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

 題目大意:一個竹竿長度為p,它的score值就是比p長度小且與且與p互質的數字總數,比如9有1,2,4,5,7,8這六個數那它的score就是6。給你T組資料,每組n個學生,每個學生都有一個幸運數字,求出要求買n個竹子每個竹子的score都要大於或等於該學生的幸運數字,每個竹竿長度就是花費,求最小花費。       

尤拉函式是指:對於一個正整數n,小於n且和n互質的正整數(包括1)的個數,記作φ(n) 。

通式:φ(x)=x*(1-1/p1)*(1-1/p2)*(1-1/p3)*(1-1/p4)…..(1-1/pn),其中p1, p2……pn為x的所有質因數,x是不為0的整數。φ(1)=1(唯一和1互質的數就是1本身)。

對於質數p,φ(p) = p - 1。注意φ(1)=1.

尤拉定理:對於互質的正整數a和n,有aφ(n) ≡ 1 mod n。

尤拉函式是積性函式——若m,n互質,φ(mn)=φ(m)φ(n)。

若n是質數p的k次冪,φ(n)=p^k-p^(k-1)=(p-1)p^(k-1),因為除了p的倍數外,其他數都跟n互質。

特殊性質:當n為奇數時,φ(2n)=φ(n)

尤拉函式還有這樣的性質:

設a為N的質因數,若(N % a == 0 && (N / a) % a == 0) 則有E(N)=E(N / a) * a;若(N % a == 0 && (N / a) % a != 0) 則有:E(N) = E(N / a) * (a - 1)。

看完上面的內容,我們就知道一根長度為p的竹竿它的score其實就是尤拉函式值φ(p)。又因為一個素數p的φ(p)=p-1,所以我們只需要從x+1(x是幸運數字)開始找第一個出現的素數,那就是最小花費。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5;
/*
bool prime[N];
int n;
void is_prime(){
    for(int i=2;i<N;i++){
        prime[i]=true;
    }
    for(int i=2;i*i<N;i++){
        if(prime[i]){
            for(int j=i*i;j<=N;j+=i){
                prime[j]=false;
            }
        }
    }
    for(int i=1;i<=N;i++)printf("%d %d\n",i,prime[i]);
}
*/
bool vis[N];
int prime[N];
int cnt;
void Eulerprim()
{

    memset(vis,0,sizeof(vis));
    for(int i=2; i<=N; i++)
    {
        if(!vis[i])
            prime[cnt++]=i;
        for(int j=0; j<cnt; j++)
        {
            if(i*prime[j]>N)
                break;
            vis[i*prime[j]]=i;
            if(i%prime[j]==0)
                break;
        }
    }
}

int main()
{
    //is_prime();
    int n;
    Eulerprim();
    int t;
    int CS=1;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        ll sum=0;
        for(int i=0;i<n;i++)
        {
            int x;
            scanf("%d",&x);
            for(int j=x+1;;j++)if(vis[j]==0){sum+=j;break;}

        }
        printf("Case %d: %lld Xukha\n",CS++,sum);
    }

    return 0;
}

                                 Aladdin and the Flying Carpet

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 ≤ 10^{12}) 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

題意:給兩個數a,b,求滿足c*d==a且c>=b且d>=b的c,d二元組對數,(c,d)和(d,c)屬於同一種情況

算術基本定理:       

分解素因數:n=(p1^k1)*(p2^k2)*...*(pn*kn).(分解方式唯一)      

n的約數個數為cnt(n)=(1+k1)*(1+k2)*...*(1+kn).

題解:

先求出a的約數個數cnt(a),再暴力枚舉出[1,b)中a的約數c,因為題目說了不會存在c==d的情況,因此cnt要除2,去掉重複情況,然後列舉小於b的a的約數,拿cnt減掉就可以了。 所以  cnt/2-c即為答案。

#include<bits/stdc++.h>
#define MAXN 1000005
using namespace std;
typedef long long ll;

int prime[MAXN];
bool vis[MAXN];
ll cnt;
ll n;
void isprime()
{
    cnt=0;
    for(int i=2;i<=MAXN;i++)
    {
        if(!vis[i])prime[cnt++]=i;
        for(int j=0;j<cnt && i*prime[j]<=MAXN;j++)
        {
            vis[i*prime[j]]=1;
            if(i%prime[j]==0)break;
        }
    }
}
ll solve()
{
    ll sum=n;
    ll ans=1;
    for(int i=0;i<cnt && prime[i]<sum;i++)
    {
        int k=0;
        while(sum%prime[i]==0)
        {
            sum/=prime[i];
            k++;
        }
        ans*=(1+k);
    }
    if(sum>1)ans*=(1+1);//多出一個素數來
    return ans;
}
int main()
{
    int t;
    int CS=1;
    isprime();
    ll d;
    scanf("%d",&t);
    ll ans;
    while(t--)
    {
        ans=0;
        ll cnt=0;
        scanf("%lld%lld",&n,&d);
        if(d*d>n)
            ans=0;
        else
        {
            for(int i=1;i<d;i++)if(n%i==0)cnt++;
            ans=solve()/2-cnt;
        }


        printf("Case %d: %lld\n",CS++,ans);

    }

    return 0;
}

                                                      Sigma Function

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 ≤ 10^{12}).

Output

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

Sample Input

4
3
10
100
1000

Sample Output

Case 1: 1
Case 2: 5
Case 3: 83
Case 4: 947

題意:1~n (n:1~10^{12})中,因子和為偶數的有幾個。

因子和 Sum=(p1^0+p1^1….p1^e1)*(p2^0+p2^1…p2^e2)……(pn^0+…pn^en); (1)

由(1)式整理得    clip_image002

(p1^0+p1^1….p1^e1),(p2^0+p2^1…p2^e2),……(pn^0+…pn^en)中只要有一個是偶數,因子和sum就為偶數。

但是因為結果為偶數不好求所以求出結果為奇數的數量,然後用總的數量 n 減去結果為奇數的數量就為最後結果ans

因為每個()裡面的就行都與 en 和 pi有關  pi^{en}

一共有四種情況   奇數(odd )偶數(even)

1. 偶^{奇}偶^{奇}even^{odd} pi為偶數 en為奇數 表示 奇數個 底數為偶數 的指數相加 一定為偶數 再加上 1(p1^{0}) 所以一定為 奇數

2.even^{even} pi為偶數 en為偶數 表示 偶數個 底數為偶數 的指數相加 一定為偶數 再加上 1(p1^{0}) 所以一定為 奇數

3.odd^{even}   pi為奇數 en為偶數 表示 偶數個 底數為奇數 的指數相加 一定為偶數 再加上 1(p1^{0}) 所以一定為 奇數

4.odd^{odd}    pi為奇數 en為奇數 表示 奇數個 底數為奇數 的指數相加 一定為奇數 再加上 1(p1^{0}) 所以一定為 偶數

在所有質數中為偶數的只有 2

所以 結果若想為奇數   2 的指數(k1) 既可以為奇數也可以為偶數 但是其他的pi為奇數時 只能為偶數 所以指數都擴大兩倍即可

1 2 3 可以整合為

2^{k1}*3^{2*k2}*5^{2*k3}*.....*(2*n-1)^{2*kn}(1)

讓  3^{k2}*5^{k3}*.....*(2*n-1)^{kn} = X

則(1)式等於 2^{k1}*X^{2}  因為 k1={0,1,2 ......}

所以 當 k1=0 時 X=sqrt(n) 當 k1!=0 時 X=sqrt(n/2) (始終讓k1=1 因為大於1其他的二可以提到X裡面去 讓其只剩下一個2)

#include<stdio.h>
#include<math.h>
typedef long long ll;
int main()
{
    int t;
    ll n;
    scanf("%d",&t);
    int CS=1;
    while(t--)
    {
        scanf("%lld",&n);
        ll ans;
        ans=n-(ll)sqrt(n)-(ll)sqrt(n/2);
        printf("Case %d: %lld\n",CS++,ans);

    }
	return 0;
}

                                          Leading and Trailing

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

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 < 2^{31}) and k (1 ≤ k ≤ 10^{7}).

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 n^{k} 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

題意:

給你一個數n和一個數k 求n^{k} 的前三位數和後三位數

題解:

後三位很好求,快速冪取模就好了,同樣前三位我們也可以模擬快速冪來寫,用double儲存答案(因為在後續相乘過程中效數也可以向前進位如果用ll的話會把小數部分捨去造成精度不夠),模擬一下快速冪,,注意輸出為3位,如果後三位是022,那麼必須輸出022,不能輸出22 (一個 %03d搞定)

#include<stdio.h>
#include<math.h>
typedef long long ll;
ll Pow(ll a,ll b,ll mod)
{
    ll ans=1;
    while(b)
    {

        if(b&1)
            ans=ans*a%mod;
        a=a*a%mod;
        b/=2;
    }
    return ans%mod;
}
double change(double x)
{
    while(x>=1000.0)
    {
        x/=10.0;
    }
    return x;
}
int main()
{
    int t;
    int CS=1;
    ll n,k;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lld%lld",&n,&k);
        int ans1=(int)Pow(n,k,1000);

        double ans2=1.0;
        double tmp=n*1.0;

        while(k)
        {
            if(k&1)
            {
                ans2=ans2*tmp;
                ans2=change(ans2);
            }
            tmp=tmp*tmp;
            tmp=change(tmp);
            k/=2;
        }
        printf("Case %d: %d %03d\n",CS++,(int)ans2,ans1);

    }
    return 0;

}

                                            Goldbach`s Conjecture

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 10^{7}.

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 ≤ 10^{7}, 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

1.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, ...

題意:

找出兩個素數相加等於n的對數。

題解; 把所有素數預處理一下 完事

if(prime[i]>=n/2+1) break; 一定要加上break 第一次T了 太菜了。。。
 

#include<stdio.h>
#include<math.h>
#define maxn 10000005
typedef long long ll;

ll prime[666666];
bool vis[maxn];
ll cnt;
void isprime()
{
    cnt=0;
    vis[1]=1;
    for(int i=2; i<=10000000; i++)
    {
        if(!vis[i])
        {
            prime[cnt++]=i;
            for(int j=i+i;j<=10000000;j+=i)vis[j]=1;
        }

    }
}

int main()
{
    int t;
    int CS=1;
    ll n;
    scanf("%d",&t);
    isprime();
    while(t--)
    {
        scanf("%lld",&n);
        ll ans=0;
        for(int i=0; i<cnt; i++)
        {
            if(prime[i]>=n/2+1) break;
            if(!vis[n-prime[i]] && prime[i]*2<=n)ans++;
        }
        printf("Case %d: %lld\n",CS++,ans);
    }
    return 0;

}

                                           Harmonic Number (II)

I was trying to solve problem '1234 - Harmonic Number', I wrote the following code

long long H( int n ) {
    long long res = 0;
    for( int i = 1; i <= n; i++ )
        res = res + n / i;
    return res;
}

Yes, my error was that I was using the integer divisions only. However, you are given n, you have to find H(n) as in my code.

Input

Input starts with an integer T (≤ 1000), denoting the number of test cases.

Each case starts with a line containing an integer n (1 ≤ n < 2^{31}).

Output

For each case, print the case number and H(n) calculated by the code.

Sample Input

11
1
2
3
4
5
6
7
8
9
10
2147483647

Sample Output

Case 1: 1
Case 2: 3
Case 3: 5
Case 4: 8
Case 5: 10
Case 6: 14
Case 7: 16
Case 8: 20
Case 9: 23
Case 10: 27
Case 11: 46475828386

題意:
求前n項和,每一項是n/i;

題解

找規律

分解單個數,可以找到規律,舉例說明。 
當n為10時: 
i     ___1   2  3  4  5  6  7  8  9  10 
n/i 10 5  3  2  2  1  1  1  1  1 
當n為12時: 
i ___1 2 3 4 5 6 7 8 9 10 
n/i 12 6 4 3 2 2 1 1 1 1 

當 tmp = 1 時,個數 是10/1 - 10/2 == 5個

當 tmp = 2 時,個數 是10/2 - 10/3 == 2個

當 tmp = 3 時,個數 是10/3 - 10/4 == 1個

…………

當 tmp = 10時,個數是10/10 - 10/11 == 1個

所以我們發現有個規律了,當tmp == i 的時候,我們要求的個數就是 10/i - 10/(i+1)

注意一點哦,關鍵是我們列舉到哪呢,若是列舉到sqrt(n),要考慮會不會有重複,什麼時候才會有重複呢?10/3=3,12/3=4,15/3=5;而他們的開方之後的結果都是3,但是如果模擬的話,會發先10的3算多了一次,也就是說,如果n/sqrt(n)==sqrt(n),那就減去sqrt(n)。 
 

#include<stdio.h>
#include<math.h>
#define maxn 10000005
typedef long long ll;



int main()
{
    int t;
    int CS=1;
    ll n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lld",&n);
        ll ans=0;
        int i;
        for(i=1; i<=sqrt(n); i++)
        {
            ans+=n/i;
            if(n/i>n/(i+1))ans+=(ll)((n/i-n/(i+1))*i);//整除可能出現相等的情況
        }
        i--;
        if(n/i==i)ans-=i;
        printf("Case %d: %lld\n",CS++,ans);
    }
    return 0;

}

                                                 Mysterious Bacteria

Dr. Mob has just discovered a Deathly Bacteria. He named it RC-01. RC-01 has a very strange reproduction system. RC-01 lives exactly x days. Now RC-01 produces exactly p new deadly Bacteria where x = b^p (where b, p are integers). More generally, x is a perfect p^th power. Given the lifetime x of a mother RC-01 you are to determine the maximum number of new RC-01 which can be produced by the mother RC-01.

Input

Input starts with an integer T (≤ 50), denoting the number of test cases.

Each case starts with a line containing an integer x. You can assume that x will have magnitude at least 2 and be within the range of a 32 bit signed integer.

Output

For each case, print the case number and the largest integer p such that x is a perfect p^th power.

Sample Input

3
17
1073741824
25

Sample Output

Case 1: 1
Case 2: 30
Case 3: 2

題意:

給你一個x,求滿足x = b^p,p最大是多少?

題解:

x可以表示為:x = p1^e1 * p2^e2 * p3^e3 ....... * pn^en。

如果x = 12 = 2^2*3^1,要讓x = b^p,及12應該是12 = 12^1

所以p = gcd (e1,e2,.......en);

比如:24 = 2^3*3^1,p應該是gcd(3, 1) = 1,即24 = 24^1

         324 = 3^4*2^2,p應該是gcd(4, 2) = 2,即324 = 18^2

本題有一個坑,就是x可能為負數,如果x為負數的話,x = b^q, q必須使奇數,所以將x轉化為正數求得的解如果是偶數的話必須將其一直除2轉化為奇數

因為 p = gcd (e1,e2,.......en); 所以可以 

p1^{e1}*p2^{e2}*p3^{e3}*...*pn^{en}

=(p1^{e1/p}*p2^{e2/p}*p3^{e3/p}*...*pn^{en/p})^{p}

=((p1^{e1/p}*p2^{e2/p}*p3^{e3/p}*...*pn^{en/p})^{2})^{p/2}

所以可以一致提出2放在裡面知道p變成奇數

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e6+7;
int prime[MAXN];
bool vis[MAXN];
ll cnt;
ll n;
ll summ[MAXN];
ll cntt;
int flag;
void isprime()
{
    cnt=0;
    for(int i=2;i<=MAXN;i++)
    {
        if(!vis[i])prime[cnt++]=i;
        for(int j=0;j<cnt && i*prime[j]<=MAXN;j++)
        {
            vis[i*prime[j]]=1;
            if(i%prime[j]==0)break;
        }
    }
}
ll solve()
{
    ll sum=n;
    ll ans=1;
    flag=0;
    for(int i=0;i<cnt && prime[i]<sum;i++)
    {
        int k=0;
        while(sum%prime[i]==0)
        {
            sum/=prime[i];
            k++;
        }
        ans*=(1+k);
        summ[cntt++]=k;
    }
    if(sum>1)ans*=(1+1),flag=1;//多出一個素數來
    //return ans;
}
int main()
{
    isprime();
    int t;

    int CS=1;
    scanf("%d",&t);
    while(t--)
    {
        int flag1=0;

        scanf("%lld",&n);

        if(n<0){n=-n,flag1=1;}
        memset(summ,0,sizeof(summ));
        cntt=0;
        solve();


        if(cntt==0)
            printf("Case %d: 1\n",CS++);//n為素數
        else
        {


                ll gcd=summ[0];
                for(int i=1;i<cntt;i++)
                    gcd=__gcd(gcd,summ[i]);

                if(flag) gcd=__gcd(gcd,1LL);

                if(flag1)//負數時p不能為偶數
                {
                    while(gcd%2==0)gcd/=2;
                }
                printf("Case %d: %lld\n",CS++,gcd);


        }

    }
    return 0;
}

                                               LCM

Ivan has number bb. He is sorting through the numbers aa from 1 to 10^18, and for every aa writes \frac{[a,b]}{a} on blackboard. Here [a,b] stands for least common multiple of aa and bb. Ivan is very lazy, that's why this task bored him soon. But he is interested in how many different numbers he would write on the board if he would finish the task. Help him to find the quantity of different numbers he would write on the board.

Input

The only line contains one integer — b (1≤b≤10^10)

Output

Print one number — answer for the problem.

Input

1

Output

1

Input

2

Output

2

Note

In the first example [a,1]=a, therefore \frac{[a,b]}{a} is always equal to 1.

In the second example [a,2] can be equal to a or 2⋅a depending on parity of a.\frac{[a,b]}{a} can be equal to 1 and 2.

題意 :

給定一個b 求 \frac{[a,b]}{a} [a,b]為a,b的最小公倍數

題解:

找b的公因數即可

太菜了。。。。。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
    ll b;
    scanf("%lld",&b);
    ll cnt=0;
    for(ll i=1;i*i<=b;i++)
    {
       // printf("==\n");
        if(b%i==0)cnt+=2;
    }
    ll x=sqrt(b);
    if(x*x==b)cnt--;
    printf("%lld\n",cnt);
    return 0;
}

                                            Pairs Forming LCM

Find the result of the following code:

long long pairsFormLCM( int n ) {
    long long res = 0;
    for( int i = 1; i <= n; i++ )
        for( int j = i; j <= n; j++ )
           if( lcm(i, j) == n ) res++; // lcm means least common multiple
    return res;
}

A straight forward implementation of the code may time out. If you analyze the code, you will find that the code actually counts the number of pairs (i, j) for which lcm(i, j) = n and (i ≤ j).

Input

Input starts with an integer T (≤ 200), denoting the number of test cases.

Each case starts with a line containing an integer n (1 ≤ n ≤ 1014).

Output

For each case, print the case number and the value returned by the function 'pairsFormLCM(n)'.

Sample Input

15
2
3
4
6
8
10
12
15
18
20
21
24
25
27
29

Sample Output

Case 1: 2
Case 2: 2
Case 3: 3
Case 4: 5
Case 5: 4
Case 6: 5
Case 7: 8
Case 8: 5
Case 9: 8
Case 10: 8
Case 11: 5
Case 12: 11
Case 13: 3
Case 14: 4
Case 15: 2

題意:在a,b中(a,b<=n)(1 ≤ n ≤ 1014),有多少組(a,b)  (a<b)滿足lcm(a,b)==n;

先來看個知識點:

素因子分解:n = p1 ^ e1 * p2 ^ e2 *..........*pn ^ en

for i in range(1,n):

        ei 從0取到ei的所有組合

必能包含所有n的因子。

現在取n的兩個因子a,b

a=p1 ^ a1 * p2 ^ a2 *..........*pn ^ an

b=p1 ^ b1 * p2 ^ b2 *..........*pn ^ bn

gcd(a,b)=p1 ^ min(a1,b1) * p2 ^ min(a2,b2) *..........*pn ^ min(an,bn)

lcm(a,b)=p1 ^ max(a1,b1) * p2 ^ max(a2,b2) *..........*pn ^ max(an,bn)

'

先對n素因子分解,n = p1 ^ e1 * p2 ^ e2 *..........*pk ^ ek,

lcm(a,b)=p1 ^ max(a1,b1) * p2 ^ max(a2,b2) *..........*pk ^ max(ak,bk)

所以,當lcm(a,b)==n時,max(a1,b1)==e1,max(a2,b2)==e2,…max(ak,bk)==ek

當ai == ei時,bi可取 [0, ei] 中的所有數  有 ei+1 種情況,bi==ei時同理。

那麼就有2(ei+1)種取法,但是當ai = bi = ei 時有重複,所以取法數為2(ei+1)-1=2*ei+1。
除了 (n, n) 所有的情況都出現了兩次  那麼滿足a<=b的有 (2*ei + 1)+1) / 2 個

注意 vis 要用bool型別 prime 用 int 否則會爆記憶體

#include<bits/stdc++.h>
const int MAXN=1e7+7;
using namespace std;
typedef long long ll;
int prime[1000005];
bool vis[MAXN];
ll cnt;
ll n;
void isprime()
{
    cnt=0;
    for(int i=2;i<MAXN;i++)
    {
        if(!vis[i])prime[cnt++]=i;
        for(int j=0;j<cnt && i*prime[j]<MAXN;j++)
        {
            vis[i*prime[j]]=1;
            if(i%prime[j]==0)break;
        }
    }
    //printf("%lld\n",cnt);
}

ll solve()
{
    ll sum=n;
    ll ans=1;
    for(int i=0;i<cnt && prime[i]*prime[i]<=sum;i++)
    {
        ll k=0;
        while(sum%prime[i]==0)
        {
            sum/=prime[i];
            k++;
        }
        ans*=(2*k+1);
    }
    if(sum>1)ans*=(2*1+1);//多出一個素數來

    return ans;
}


int main()
{
    int t;
    int CS=1;
    isprime();

    scanf("%d",&t);

    while(t--)
    {
        scanf("%lld",&n);
        ll anss=solve();

        printf("Case %d: %lld\n",CS++,(anss+1)/2);
    }

    return 0;
}

                                         Harmonic Number

In mathematics, the n^th harmonic number is the sum of the reciprocals of the first n natural numbers:

In this problem, you are given n, you have to find Hn.

Input

Input starts with an integer T (≤ 10000), denoting the number of test cases.

Each case starts with a line containing an integer n (1 ≤ n ≤ 10^8).

Output

For each case, print the case number and the n^th harmonic number. Errors less than 10^-8 will be ignored.

Sample Input

12
1
2
3
4
5
6
7
8
9
90000000
99999999
100000000

Sample Output

Case 1: 1
Case 2: 1.5
Case 3: 1.8333333333
Case 4: 2.0833333333
Case 5: 2.2833333333
Case 6: 2.450
Case 7: 2.5928571429
Case 8: 2.7178571429
Case 9: 2.8289682540
Case 10: 18.8925358988
Case 11: 18.9978964039
Case 12: 18.9978964139

題意:

 求Hn

題解

1.精度能保證在10 ^-8就沒問題,直接用%.10lf 即可;2. n的範圍是10^8,肯定不能正常跑,但是可以用公式,前面10000個可以正常打表,後面的我們就用公式,因為,這個公式成立的 條件,是在n比較大的時候,公式如下: 
r為常數,r=0.57721566490153286060651209(r就是尤拉常數)。

由於題目要求精度為10^-8,常數r也是前人推匯出來的,然而也只推導了有限位數,所以正常利用這個公式,並不能達到精度要求,我們只好比較樣例和我們自己輸出的資料,增添一些可行的項,經嘗試,在原公式的基礎上,再減去一個1.0/(2*n)恰好可以滿足精度

 c++ math庫中,log即為ln。

所以就有兩個公式

Hn=log(n+1)+r-1.0/(2*n);

Hn=log(n)+r+1.0/(2*n); (親測有效)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e7+7;
const double c=0.57721566490153286060651209;
double a[10010];
int main()
{
    int t;
    int n;
    int CS=1;
    a[1]=1;
    for(int i=2;i<=10000;i++)
        a[i]=a[i-1]+1.0/i;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        printf("Case %d: ",CS++);
        if(n<=10000)
        {
            printf("%.10f\n",a[n]);
        }
        else
        {
            //double ans=log(n+1)+c-1.0/(2*n);
            double ans=log(n)+c+1.0/(2*n);
            printf("%.10f\n",ans);
        }

    }
    return 0;
}

                                                  Large Division

Given two integers, a and b, you should check whether a is divisible by b or not. We know that an integer a is divisible by an integer b if and only if there exists an integer c such that a = b * c.

Input

nput starts with an integer T (≤ 525), denoting the number of test cases.

Each case starts with a line containing two integers a (-10^200 ≤ a ≤ 10^200) and b (|b| > 0, b fits into a 32 bit signed integer). Numbers will not contain leading zeroes.

Output

For each case, print the case number first. Then print 'divisible' if a is divisible by b. Otherwise print 'not divisible'.

Sample Input

6
101 101
0 67
-101 101
7678123668327637674887634 101
11010000000000000000 256
-202202202202000202202202 -101

Sample Output

Case 1: divisible
Case 2: divisible
Case 3: divisible
Case 4: not divisible
Case 5: divisible
Case 6: divisible

題意:

給一個a(大數)和一個b判斷a是否能整除b

題解:

因為a是大數所以用字串存,for迴圈跑字元長度每次都對b取模,看最後ans是否為0

ans=((ans*10)%b+(a[i]-'0')%b)%b;

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e6+7;
char a[MAXN];
int main()
{
   int t;

   ll b;
   int CS=1;
   scanf("%d",&t);
   while(t--)
   {
       scanf("%s%lld",a,&b);
       int l=strlen(a);
       if(b<0)b=-b;
       ll ans=0;
       for(int i=0;i<l;i++)
       {
           if(a[i]=='-')continue;
           ans=((ans*10)%b+(a[i]-'0')%b)%b;
       }


       ans%=b;

        printf("Case %d: ",CS++);

        if(ans)printf("not divisible\n");
        else printf("divisible\n");
   }
    return 0;
}

                                           Trailing Zeroes (III)

You task is to find minimal natural number N, so that N! contains exactly Q zeroes on the trail in decimal notation. As you know N! = 1*2*...*N. For example, 5! = 120, 120 contains one zero on the trail.

Input

Input starts with an integer T (≤ 10000), denoting the number of test cases.

Each case contains an integer Q (1 ≤ Q ≤ 108) in a line.

Output

For each case, print the case number and N. If no solution is found then print 'impossible'.

Sample Input

3
1
2
5

Sample Output

Case 1: 5
Case 2: 10
Case 3: impossible

題意:

給你一個數字,這個數字代表N!後面0的個數。給出這個數字,求N的值。

題解:

有算數基本定理可知 N!可劃分為 質因數相乘的形式  N!=2^a*3^b*5^c*7^d........
因為只有2*5 才會出現 0   又因為2的數量肯定比5的多  所以計算階乘中5的數量就可以得到該階乘後有幾個0。
50/5=10  10/5=2  所以50!後有10+2=12個0。

二分N的值即可

注意二分的位置

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define linf 0x3f3f3f3f3f3f3f3f
ll sum(ll x)
{
    ll sum=0;
    while(x)
    {
        sum+=x/5;
        x/=5;
    }
    return sum;
}
int main()
{
   int t;
   ll q;
   int CS=1;
   scanf("%d",&t);
   while(t--)
   {
       scanf("%lld",&q);

       ll l=0;
       ll r=linf;
       ll ans;
       while(l<=r)
       {
           ll mid=(l+r)/2;
           if(sum(mid)>=q)ans=mid,r=mid-1;//因為此位置是r=mid+1所以最會準確值為r-1,如果為l=mid-1則最後結果為l+1
           else l=mid+1;
       }
       if(sum(l+1)!=q)printf("Case %d: impossible\n",CS++);
       else printf("Case %d: %lld\n",CS++,ans);




   }

    return 0;
}