算法竞赛入门10.1数论初步例题代码

10.1 Colossal Fibonacci Numbers! UVA11582

思路:循环节+快速幂

#include<cstdio>
#include<cstring>
#include<algorithm>

#define  LLu long long unsigned
using namespace std;

inline int qpow(LLu x,LLu y ,int MOD)
{
    x%=MOD;
    LLu ans = 1,tem = x ;
    while(y)
    {
        if(y&1)ans = (ans*tem)%MOD;
        tem = (tem * tem) %MOD;
        y/=2;
    }return (int)ans ;
}
LLu A[1000000+5];//1 1 2 3 5 8 13 21

inline void print(int n)
{
    for(int i=0;i<n;i++)
        printf("%llu %llu\n",A[i],A[i+1]);
}

int main()
{
    LLu a,b;
    int T;scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%llu%llu%d",&a,&b,&n);
        A[0]=0%n;A[1]=1%n;int m=n*n;
        for(int i=2;i<=m;i++)
        {
            A[i]=(A[i-1]+A[i-2])%n;
            if(A[i]==A[1]&&A[i-1]==A[0])
            {
                n=i-1 ;
                break;
            }
        }//print(n);
        int ans = qpow(a,b,n);//printf("ans = %d\n",ans);
        printf("%llu\n",A[ans]);
    }
}

10.3 Choose and Divide UVA10375

思路:唯一分解出所有素数个数

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define __int64 long long
using namespace std;
const int N = 10000+5;
inline __int64 C(__int64 n,__int64 m)
{

}
int prime[2000];
int num[2000l];
bool judge_prime[N]={0};
inline int init()
{
    int num = 0 ;
    memset(judge_prime,false,sizeof(judge_prime));
    for(int i=2;i<N;i++)
    {
        if(!judge_prime[i]){
            prime[num++]=i;
            for(int j=i*i;j<N;j+=i)
                judge_prime[j]=true;
        }
    }return num ;
}

inline void add_primefactor(int n,int d,int primenum){
    for(int i=0;i<primenum&&n>1;i++)
    {
        while(n%prime[i]==0){
            num[i]+=d;
            n/=prime[i];
        }
    }
}

inline void add_fun(int n,int d,int primenum)
{
    for(int i=2;i<=n;i++)
        add_primefactor(i,d,primenum);
}

void print(int n)
{
    for(int i=0;i<n;i++)
        printf("%d -- >  %d\n",prime[i],num[i]),getchar();
}

inline void work(int a,int b,int c,int d,int primenum)
{
    add_fun(a,1,primenum);
    add_fun(c,-1,primenum);
    add_fun(b,-1,primenum);
    add_fun(d,1,primenum);
    add_fun(a-b,-1,primenum);
    add_fun(c-d,1,primenum);
}

int main()
{
    int primenum = init();
    int a,b,c,d;
    while(scanf("%d%d%d%d",&a,&b,&c,&d)==4)
    {
        memset(num,0,sizeof(num));
        work(a,b,c,d,primenum);
        double ans = 1;
        for(int i=0;i<primenum;i++)
        {
            ans *= pow(prime[i],num[i]);
            if(prime[i]>=max(a,c))break;
        }
        printf("%.5f\n",ans);
    }

}


10.4 Minimun Sum LCM UVA10791

思路:唯一分解

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

inline int work(int a,int& x){
    int res = 1;
    while(x%a==0){
        res*=a;
        x/=a;
    }return res;
}

int main()
{
    int n,t=0;
    while(scanf("%d",&n)==1&&n)
    {
        if(n==1){
            printf("Case %d: %d\n",++t,2);
            continue;
        }
        int k=0;
        long long ans = (long long)n+1;
        int cur = 0;int m=n/2;
        for(int i=2;i<=m&&i<=n;i++)
        {
            if(n%i==0){
                k++;
                cur += work(i,n);
            }
        }//printf("cur=%d\n",cur);
        if(cur){
            ans = min( ans , k<2?cur+1LL:cur+0LL );
        }
        printf("Case %d: %lld\n",++t,ans);
    }
}



10.5 GCD XOR  UVA12716


思路:异或的基本性质 :a^b=c,a^c=b  +  筛素数

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 30000000+5;
int A[N];
inline void init()
{
    int x = N ;
    memset(A,0,sizeof(A));
    for(int i=1;i<=x;i++)
    {
        A[i]+=A[i-1];
        for(int j=i*2;j<=x;j+=i)
        {
            int l= j^i;
            if(j>l&&(j-l)==i)
                A[j]++;//printf("a=%d,b=%d,c=%d\n",j,j^i,i);
        }
    }
}

int main()
{
    int T,t=0;init();
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        printf("Case %d: %d\n",++t,A[n]);
    }
}



你可能感兴趣的:(数论,ACM,算法竞赛入门经典,刘汝佳)