(JZ1161)2018.07.09【2018提高組】模擬B組 2.機器人M號

機器人M號 (Standard IO)

Description

3030年,Macsy正在火星部署一批機器人。 第1秒,他把機器人1號運到了火星,機器人1號可以製造其他的機器人。 第2秒,機器人1號造出了第一個機器人——機器人2號。 第3秒,機器人1號造出了另一個機器人——機器人3號。 之後每一秒,機器人1號都可以造出一個新的機器人。第m秒造出的機器人編號爲m。我們可以稱它爲機器人m號,或者m號機器人。 機器人造出來後,馬上開始工作。m號機器人,每m秒會休息一次。比如3號機器人,會在第6,9,12,……秒休息,而其它時間都在工作。 機器人休息時,它的記憶將會被移植到當時出生的機器人的腦中。比如6號機器人出生時,2,3號機器人正在休息,因此,6號機器人會收到第2,3號機器人的記憶副本。我們稱第2,3號機器人是6號機器人的老師。 如果兩個機器人沒有師徒關係,且沒有共同的老師,則稱這兩個機器人的知識是互相獨立的。注意:1號機器人與其他所有機器人的知識獨立(因爲只有1號纔會造機器人),它也不是任何機器人的老師。 一個機器人的獨立數,是指所有編號比它小且與它知識互相獨立的機器人的個數。比如1號機器人的獨立數爲0,2號機器人的獨立數爲1(1號機器人與它知識互相獨立),6號機器人的獨立數爲2(1,5號機器人與它知識互相獨立,2,3號機器人都是它的老師,而4號機器人與它有共同的老師——2號機器人)。 新造出來的機器人有3種不同的職業。對於編號爲m的機器人,如果能把m分解成偶數個不同奇素數的積,則它是政客,例如編號15;否則,如果m本身就是奇素數或者能把m分解成奇數個不同奇素數的積,則它是軍人,例如編號 3, 編號165。其它編號的機器人都是學者,例如編號2, 編號6, 編號9。 第m秒誕生的機器人m號,想知道它和它的老師中,所有政客的獨立數之和,所有軍人的獨立數之和,以及所有學者的獨立數之和。可機器人m號忙於工作沒時間計算,你能夠幫助它嗎? 爲了方便你的計算,Macsy已經幫你做了m的素因子分解。爲了輸出方便,只要求輸出總和除以10000的餘數。

Input

輸入文件的第一行是一個正整數k(1<=k<=1000),k是m的不同的素因子個數。 以下k行,每行兩個整數,pi, ei,表示m的第i個素因子和它的指數(i = 1, 2, …, k)。p1, p2, …, pk是不同的素數。所有素因子按照從小到大排列,即p1

Output

輸出文件包括三行。 第一行是機器人m號和它的老師中,所有政客的獨立數之和除以10000的餘數。 第二行是機器人m號和它的老師中,所有軍人的獨立數之和除以10000的餘數。 第三行是機器人m號和它的老師中,所有學者的獨立數之和除以10000的餘數。

Sample Input

3 2 1 3 2 5 1

Sample Output

8 6 75

Data Constraint

Hint

樣例解釋: m=2*3^2*5=90。90號機器人有10個老師,加上它自己共11個。其中政客只有15號;軍人有3號和5號;學者有8個,它們的編號分別是:2,6,9,10,18,30,45,90。

題解:

    本題是歐拉函數+快速冪(與機器人真的沒有關係…╮(╯▽╰)╭)
    一個數a的獨立數是指比 a 小且與 a 互質的數(包括 1);一個數 a 的老師是指這個數的因數(不包括 1 和 a)
    現在我們有三類數:

  • 第一類(政客):對於 m,如果能把 m 分解成偶數個不同奇素數的積,則它是政客。  例如 15(3*5)
  • 第二類(軍人):對於 m,如果 m 本身就是奇素數或者能把 m 分解成奇數個不同奇素數的積,則它是軍人。  例如 3, 165(3*5*11)。
  • 第三類(學者):對於 m,m 既不是政客又不是軍人,則它是學者。

       對於一個數的獨立數其實就是它的歐拉函數和,設f[i]爲m的所有大於2的質因數中的選擇i個質因數的歐拉函數和。∑f[i],當i爲偶數時即爲政客的獨立數和;當i爲奇數時即爲政客的獨立數和
       那麼學者的獨立數和呢?因爲學者既不是政客又不是軍人,但包括在m中,所以學者的獨立數和=m-軍人-政客-1

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
const int mod=10000;
int k,p[1010],e[1010],f[1010],ans1,ans2,ans3,g;
int mi(int a,int b)//快速冪
{
    int x=1;
    while (b)
    {
        if (b%2) x=(x*a)%mod;
        b/=2;
        a=(a*a)%mod;
    }
    return x;
}
int main()
{
    ans3=1;
    scanf("%d",&k);
    for (int i=1;i<=k;i++) scanf("%d%d",&p[i],&e[i]);
    if (p[1]==2) g=2; 
            else g=1;
    f[0]=1;
    for (int i=g;i<=k;i++)
        for (int j=i-g+1;j>=1;j--)
            f[j]=(f[j]+f[j-1]*(p[i]-1))%mod;
    for (int i=1;i<=k-g+1;i++)
        if (i%2) ans2=(ans2+f[i])%mod; 
            else ans1=(ans1+f[i])%mod;
    for (int i=1;i<=k;i++) ans3=(ans3*mi(p[i],e[i]))%mod;
    ans3=(ans3+10000000-ans1-ans2-1)%mod;
    printf("%d\n%d\n%d\n",ans1,ans2,ans3);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章