HIT@wh热身赛题解

热身赛,内网

A. A+B Problem

简单的按数据组数进行的A+B,直接贴代码吧

#include<cstdio>
using namespace std;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        printf("%d\n",a+b);
    }
    return 0;
}

B. 亲和数

一句话题意

给定两个数,求它们的因数是不是相同

题目分析

求解因数的程序吧,注意特判一下
i i = = n i * i == n
这种情况只能加一次,而不是加两次

代码

#include<bits/stdc++.h>
using namespace std;
long long Calc(int x){
    long long add = 0;
    for(int i=1;i*i<=x;++i){
        if(!(x%i))
            add += i + x/i;
        if(i*i == x)
            add -= i;
    }
    return add;
}
void Work(){
    long long a,b;
    scanf("%lld %lld",&a,&b);
    if(Calc(a)==Calc(b))
        printf("Yes\n");
    else
        printf("No\n");
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--)
        Work();
    return 0;
}

C. 斐波那契数列

一句话题意

给你一个 n < 1 e 18 + 1 n < 1e18+1 求斐波那契数列的第 n n 项。

分析

朴素斐波那契算法的复杂度是 O ( n ) O(n)
显然不行。

矩阵法

[ 1 1 1 0 ] (1) \begin{bmatrix} 1 & 1\\ 1 & 0 \end{bmatrix} \tag{1}

[ 1 1 ] (2) \begin{bmatrix} 1\\ 1 \end{bmatrix} \tag{2}
斐波那契数列的第 k k 项,可以表示为
矩阵(1)的(k-2)次方乘矩阵(2)之后的第一行代表的项。

于是结合快速幂算法,我们就可以搞到
O ( l o g 2 k ) O(log_{2}k)

然后这个题就过了耶~

代码

#include<bits/stdc++.h>
using namespace std;
const long long MOD = 1e9+7;
struct Matrix{
    long long a[2][2];
    Matrix(){
        a[0][0]=a[0][1]=a[1][0]=a[1][1]=0;
    }
}Ans,Tep;
Matrix Mul(Matrix a,Matrix b){
    Matrix c;
    for(int i=0;i<2;++i)
        for(int j=0;j<2;++j)
            for(int k=0;k<2;++k)
                c.a[i][j] = (c.a[i][j] + (a.a[i][k] * b.a[k][j])%MOD)%MOD;
    return c;
}
int main(){
    long long T;
    scanf("%lld",&T);
    if(T<=2){
        printf("1");
        return 0;
    }
    T-=2;
    Tep.a[0][0]=Tep.a[0][1]=Tep.a[1][0]=1;
    Ans.a[0][0]=Ans.a[1][1]=1;
    while(T){
        if(T&1)
            Ans = Mul(Ans,Tep);
        Tep = Mul(Tep,Tep);
        T>>=1;
    }
    long long ans = (Ans.a[0][0] + Ans.a[0][1])%MOD;
    printf("%lld",ans);
    return 0;
}

C. 暴力解法

首先,如果你一个算式一直对同一个数P取模,那么他一定会出现循环节,且循环节不大于P的Q次方,其中Q为有贡献的式子的数量(例如F[i]=F[i-1]+F[i-2],Q=2).

抱着试一试的心态,找了一下循环节。
咦~真的存在

#include<bits/stdc++.h>
using namespace std;
const long long MOD = 1e9+7;
long long Temp[2];
int main(){
    Temp[0] = Temp[1] = 1;
    for(long long i = 3;;++i){
        if(i!=3 && Temp[i&1] == 1 && Temp[(i&1)^1]==0){
            printf("%lld\n",i-1);
            break;
        }
        Temp[i&1] = (Temp[0] + Temp[1])%MOD;
    }
    return 0;
}

循环节是 2000000016 2000000016

然后就进入了暴力打表的过程中了~

由于计算机稳定计算的次数大概为 1 e 8 1e8
我们不妨每 1 e 7 1e7 记录一下 F [ i 1 e 7 ] , F [ i 1 e 7 + 1 ] F[i*1e7],F[i*1e7+1] ,然后就暴力计算这个 1 e 7 1e7 之内的结果就可以了。

然后就输出一下每个 1 e 7 1e7 的记录结果。

#include<bits/stdc++.h>
using namespace std;
const long long MOD = 1e9+7;
long long Temp[2];
int main(){
    freopen("CC.txt","w",stdout);
    Temp[0] = Temp[1] = 1;
    for(long long i = 3;;++i){
        if(i!=3 && Temp[i&1] == 1 && Temp[(i&1)^1]==0){
            //printf("%lld\n",i-1);
            break;
        }
        Temp[i&1] = (Temp[0] + Temp[1])%MOD;
        if((i%10000000) == 1)printf(",%lld,%lld",Temp[(i&1)^1],Temp[i&1]);
    }
    return 0;
}

然后,就进入了暴力算式的结果

#include<bits/stdc++.h>
using namespace std;
const long long MOD = 1e9+7,P = 2000000016,SZ = 1e7+17,SQ = 1e7;
long long Biao[427]={0,1,490189494,640540120,877218207,803548776,792336636,808851781,865390300,196976169,364822946,345273904,34721793,400398684,211176624,324203083,489276259,974106729,560674156,865342814,908460138,945351196,663959822,537402860,351309356,927393756,34728542,846909185,946297609,502819837,646371660,357890353,845895238,786188346,490220918,754032189,981951309,505535123,384152217,5878240,371975563,80688602,71343585,176887776,396013987,58939966,341094152,175761349,47125963,396580227,431043837,209556590,370146386,237581351,872482683,403215026,829535814,241674835,303189210,801393168,967988087,800447448,584343994,49657722,132225666,721876347,306710464,552449914,848719223,830726857,417590676,503416162,103684887,294879735,636741114,458492591,31497600,498260343,550090373,160506850,392460984,947746097,688807392,267466228,903333739,164224057,34803879,775227299,729987547,369610353,541353446,992016211,29563180,300238008,779310126,470469544,573486682,719571781,793777511,221450476,864787550,220121405,969567541,770923794,566334113,57673489,10891922,649415011,689319466,860400491,869935040,772961815,251655405,355165112,732223594,643614158,192043699,638417417,571286786,12479963,4660654,539612979,521818629,512688015,872935933,270634790,905978774,945667489,540377917,337084384,418078,114864556,478613700,410797201,588684121,364467476,878336833,557802238,639284028,679697704,393241336,850278613,770716118,156375227,859137012,221940703,809790292,778343289,801111326,950271398,4258201,827413683,940822230,467449387,125212249,986349289,385921075,65668574,642109873,129710253,530142919,975243705,117421826,850365172,381604439,572433034,207547749,275814297,506593171,12389717,918528888,176452201,861085340,892961352,236563805,712352343,42290336,133406429,916937613,702084335,662356693,442753488,460962947,265150282,816832494,422402570,553560792,95946971,859755617,517042806,993450205,592855736,386573344,516187473,286263480,146233878,278360791,536120382,823805809,751462579,21,999999994,784899752,966957807,49105349,975448210,46441847,123996161,713229531,612505998,846771862,172721093,227831353,523974796,628259534,220069025,820848482,611413983,109277797,524700694,964730508,788097308,710826196,956919040,530750723,321377683,604322345,719480054,385098025,335591817,539061078,921230215,749517265,543351451,167164764,492220821,229893238,49020792,62267753,990779388,47291577,762534955,288961399,198674204,773263819,550074120,93787217,878079627,725901983,834102307,745198009,327684865,404231303,684516515,803104478,80340914,870954027,278479141,520823346,948862261,897801569,921932940,175116499,625673411,663730573,392346524,173292411,259070869,588810499,23654493,373656446,224994076,667188263,343946086,979146626,411159662,392548740,184065183,667571280,465308720,558994539,920981438,197339586,987894198,735358267,835095666,96441288,652926642,942240941,524803828,426323253,472211637,299850013,717732704,383316259,249408504,612460248,688787155,662024783,790471452,219772980,298960180,224103399,338908969,955783560,143260939,267389792,786335282,631548509,290502382,654406853,220132189,902183596,667617049,620295206,9711371,877279949,733491293,838328639,834782910,173410246,82905056,24614978,293246986,3509036,813402225,55739030,731876855,705922970,965839223,397941010,515540424,353875477,710524059,638556973,624289304,850394809,193644322,537994888,588894408,485645421,204446108,79531916,152160429,450096530,156648008,812339225,887133333,717914330,469809644,230908390,333044419,828481468,680424708,456118491,806916549,257723588,250651064,892179771,798073967,455258545,454833148,865326437,411111173,46542795,572063777,735476785,772916868,36016362,477390200,475514225,995227923,475286909,474294522,916229791,707259481,363663578,153813486,567892312,128593448,777695784,153695153,895415801,233268179,98149307,662248887,193819582,377465939,626208081,333311402,672663640,155329646,696443258,407603068,337953167,110492638,794261121,876011659,771316744,530908413,999999020,610};
int F[SZ];
int main(){
    long long T;scanf("%lld",&T);T%=P;
    long long ps = T/SQ;
    F[0] = Biao[ps<<1];
    F[1] = Biao[ps<<1|1];
    T%=SQ;
    for(int i=2;i<=T;++i){
        F[i] = (F[i-1] + F[i-2])%MOD;
    }
    printf("%d",F[T]);
    return 0;
}

有一说一这个真的不用矩阵快速幂

猜你喜欢

转载自blog.csdn.net/H_18763886211/article/details/103650887