數學考試2(test20170311)

【傻牛的遞推數列】(sequence.pas/c/cpp Time:1s Memory:256M)

【問題描述】

傻牛最近鑽研各類數學遞推數列。尤其是斐波那契數列。

傻牛眼中的斐波那契數列是這樣的,F1=1,F2=1 ,然後Fi+2=Fi+1+Fi ,逐項遞推。

今天,傻牛發現,某些斐波那契項之間是成倍數關係的。例如第4項F4=3 和第8項F8=21 。傻牛想知道,對於某一項Fx ,求所有滿足FiFxFi 倍數的i的和是多少?

【輸入】

輸入文件名sequence.in。

輸入包含若干組數據,每組數據一行包括一個正整數X,意義如上。

【輸出】

輸出文件名sequence.out

輸出包含若干行,每行對應每組數據的解。

【輸入輸出樣例】

Sequence.in
4
Sequence.out
7
【輸入輸出解釋】

F1 ,F2 ,F4F4 的約數,所以權值爲1+2+4=7

【數據範圍】

對於60%的數據,保證有X≤1000000,數據組數等於1。

對於100%的數據,保證有X≤1000000,數據組數小於等於100000。

【題解】

反正對於數學題,首先就是打暴力,再打表,然後再找規律,這個題也不例外,經打表可以發現答案就爲 x 的約數和,當 x 爲奇數的時候還要加上 2。

所以問題轉化爲求一個數的約數和即可

關於求約數和,有約數和公式:

對於已經分解的整數

A=p1k1×p2k2×p3k3××pnkn

有A的所有因子之和爲

S=(1+p1+p12+p13++p1k1)×(1+p2+p22+p23++p2k2)×(1+p3+p32+p33++p3k3)×(1+pn+pn2+pn3++pnkn)

【代碼】

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;

const int size = 1000010;
typedef long long LL;
LL n,rans,prime[size],fir[size];
bool no_prime[size];

void pre_prime() {
    for(LL i=2;i<=size;i++){
        if(!no_prime[i]) {
            prime[++prime[0]]=i;fir[i]=prime[0];
        }
        for(LL j=1;prime[j]*i<=size;j++){
            fir[prime[j]*i]=j;
            no_prime[prime[j]*i]=true;
            if(i%prime[j]==0)break;
        }
    }
}

void work(LL x,LL ans){
    if(x==1) {
        rans=ans;return;
    }
    LL tmp=prime[fir[x]],tt=prime[fir[x]],equ=1;
    while(x%tmp==0) {
        equ+=tt;
        tt=tt*tmp;
        x/=tmp;
    }
    work(x,ans*equ);
}

int main() {
    freopen("sequence.in","r",stdin);
    freopen("sequence.out","w",stdout);
    pre_prime();
    while(~scanf("%lld",&n)) {
        work(n,1);
        if(n&1)
            rans+=2;
        printf("%lld\n",rans);
    }
    return 0;
}

【傻牛的數字遊戲】(Game.pas/c/cpp Time:1s Memory:256M)

【問題描述】

傻牛最近在玩一個數字遊戲。

首先,規定一個神奇的數字P,它就是1000000007。

這個遊戲是這樣的,首先給你一個無比巨大的數字1000000006!1000000006 ,當然,這個數字對P的模值爲1。然後,遊戲可能給你以下兩種操作之一,第一種操作就是將這個數乘以一個數字X,第二種操作就是將這個數字除以一個數字X。要求輸出每種操作過後這個數字對P的模值。現在,傻牛的菊花癢了,要去上廁所了,你不得不幫他玩一盤。

【輸入】

輸入文件名Game.in。

一行一個數字N代表操作總數。

接下N行代表順次的N個操作,每個操作佔一行,按“A X”格式給出,A=1時代表操作1,A=2時代表操作2。

【輸出】

輸出文件名Game.out。

輸出包含N行,每行對應這個操作結束時這個數字對P的模值。

【輸入輸出樣例】

Game.in
2
1 2
2 2
Game.out
2
1
【數據範圍】

對於40%的數據,保證有A=1。

對於100%的數據,保證有N1051XP1

【題解】

我們可以一眼看出A=1的時候就是將答案直接乘上X即可,輕鬆40分。(爲什麼的話自行度娘)

然後其實100分的話也好拿,學了逆元的話直接秒掉,總之這題水的一B。

【代碼】

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;

const int MOD = 1000000007;
typedef long long LL;
LL n,ans=1;

LL ksm(LL x,LL y,LL Mod);
LL read();

int main() {
    freopen("game.in","r",stdin);
    freopen("game.out","w",stdout);
    n=read();
    for(LL i=1,op,x;i<=n;i++) {
        op=read();x=read();
        if(op==1){
            ans=ans*x%MOD;
            printf("%lld\n",ans);
        }
        else{
            LL ret=ksm(x,MOD-2,MOD);
            ans=ans*ret%MOD;
            printf("%lld\n",ans);
        }
    }
    return 0;
}

LL ksm(LL x,LL y,LL Mod) {
    x%=Mod;
    LL ret=1;
    while(y){
        if(y&1)
            ret=ret*x%Mod;
        x=x*x%Mod;
        y>>=1;
    }
    return ret;
}

LL read() {
    LL ans=0;
    char ch=getchar();
    while(ch<'0'||ch>'9')
        ch=getchar();
    while(ch>='0'&&ch<='9') {
        ans=ans*10+ch-'0';ch=getchar();
    }
    return ans;
}

【傻牛的約數研究】(divisor.pas/c/cpp Time:1s Memory:256M)

【問題描述】

傻牛最近在研究約數,它覺得這玩意很牛逼。

首先,對於一個數字X來說,設F(X) 表示X的約數個數,可以先將X表達成爲若干個質數的冪次之積,即X=p1k1×p2k2××psks ,然後F(X)=(k1+1)×(k2+1)××(ks+1) 。傻牛覺得這個碉堡了。有一天它想,我們是不是可以求出F(1)+F(2)+F(3)++F(N) 的值呢?結果,它暈掉了。

【輸入】

輸入文件名爲divisor.in。

一行一個整數N,意義見上。

【輸出】

輸出文件名爲divisor.out。

一行一個整數,代表傻牛想求出的值。

【輸入輸出樣例】

Divisor.in
4
Divisor.out
8
【樣例解釋】

F(1)+F(2)+F(3)+F(4)=1+2+2+3=8 .

【數據範圍】

對於50%的數據,保證有N≤103。

對於100%的數據,保證有N≤106。

【題解】

這題目還可以再水一些,核心代碼只有四行就可以A掉此題,不要問我爲什麼,因爲我也不知道。。。

核心代碼:

scanf("%d",&n);
for(int i=1;i<=n;i++)
ans+=n/i;
printf("%d\n",ans);

【代碼】

該代碼爲pyh的分塊代碼,據說可以降到O(n) 了。

#include <iostream>
#include <cstdio>

#define LL long long

using namespace std;

LL x,ans;

int main(){

    freopen("divisor.in","r",stdin);
    freopen("divisor.out","w",stdout);

    scanf("%lld",&x);

    for(LL i=1,it;i<=x;i=it+1){
        it=x/(x/i);
        ans+=(x/i)*(it-i+1);
    }

    printf("%lld\n",ans);

    return 0;
}

總結

今天的考試是今年第一次AK,值得慶祝,不過主要是因爲題目還是有點水了,下午的考試於是就GG了。。。

發佈了39 篇原創文章 · 獲贊 7 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章