数论 2016.4.9

1、FZU 1402 猪的安家

典型中国剩余定理

#include <iostream>
#include <cstdio>

using namespace std;

typedef long long LL;

const int maxn = 1000 + 5;
int a[maxn], b[maxn];
LL x, y;

LL Ext_Gcd(LL a, LL b, LL &x, LL &y);

int main()
{
//    freopen("in.txt", "r", stdin);
    int n;

    while (cin>>n) {
        LL mul = 1;
        for (int i=0; i<n; ++i) {
            cin>>a[i]>>b[i];
            mul *= a[i];
        }
        LL ans = 0;
        for (int i=0; i<n; ++i) {
            LL t = mul/a[i];
            Ext_Gcd(t, a[i], x, y);
            x = (x%a[i] + a[i]) % a[i];
            ans = (ans + t * x * b[i]) % mul;
        }
        cout<<ans<<endl;
    }
    return 0;
}

LL Ext_Gcd(LL a, LL b, LL &x, LL &y)
{
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    int d = Ext_Gcd(b, a%b, x, y);
    int t = x;
    x = y;
    y = t - a/b*y;
    return d;
}

2、POJ 1995 Raising Modulo Numbers

最简单的快速幂

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

typedef long long LL;

LL pow_mod(LL x, LL n, LL mod_val);

int main()
{
//    freopen("in.txt", "r", stdin);
    int Z;

    scanf("%d", &Z);
    while (Z--) {
        int ans = 0;
        int M;
        scanf("%d", &M);
        int H;
        scanf("%d", &H);
        int A, B;
        for (int i=0; i<H; ++i) {
            scanf("%d%d", &A, &B);
            ans = (ans + pow_mod(A%M, B, M)) % M;
        }
        printf("%d\n", ans);
    }
    return 0;
}

LL pow_mod(LL x, LL n, LL mod_val)
{
    LL ret = 1;
    LL t = x % mod_val;
    while (n) {
        if (n&1) {
            ret = (ret * t) % mod_val;
        }
        t = (t * t) % mod_val;
        n >>= 1;
    }
    return ret;
}

3、UVa 408 Uniform Generator

gcd

#include <iostream>
#include <cstdio>
#include <cstring>
#include <iomanip>

using namespace std;

int Gcd(int a, int b);

int main()
{
//    freopen("in.txt", "r", stdin);
    int a, b;

    while (cin>>a>>b) {
        if (Gcd(a, b) == 1) {
            cout<<setw(10)<<setfill(' ')<<a;
            cout<<setw(10)<<setfill(' ')<<b;
            cout<<"    Good Choice"<<endl;
        } else {
            cout<<setw(10)<<setfill(' ')<<a;
            cout<<setw(10)<<setfill(' ')<<b;
            cout<<"    Bad Choice"<<endl;
        }
        cout<<endl;
    }
    return 0;
}

int Gcd(int a, int b)
{
    return ((a%b == 0) ? b : Gcd(b, a%b));
}

4、HDU 2098 分拆素数和

素数筛,可暴力

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int maxn = 10000 + 10;
bool IsPrime[maxn];

void Init(void);

int main()
{
//    freopen("in.txt", "r", stdin);
    int N;
    Init();

    while (cin>>N && N!=0) {
        int Count = 0;
        for (int i=2; i<N/2; ++i) {
            if (IsPrime[i] && IsPrime[N-i]) {
                ++Count;
            }
        }
        cout<<Count<<endl;
    }
    return 0;
}

void Init(void)
{
    memset(IsPrime, true, sizeof(IsPrime));
    for (int i=2; i<=maxn; ++i) {
        if (IsPrime[i]) {
            int j = 2;
            while (i*j <= maxn) {
                IsPrime[i*j] = false;
                ++j;
            }
        }
    }
}

5、HDU 1061 Rightmost Digit

稳定的快速幂模版

#include <iostream>

using namespace std;

typedef long long LL;

LL pow_mod(LL x, LL n, LL mod_val);
LL mult_mod(LL x, LL y, LL mod_val);

int main()
{
    int T;
    int N;

    while (cin>>T) {
        while (T--) {
            cin>>N;
            cout<<pow_mod(N, N, 10)<<endl;
        }
    }
    return 0;
}

LL mult_mod(LL a, LL b, LL mod_val)
{
    a %= mod_val;
    b %= mod_val;
    LL ret = 0;
    LL t = a;
    while (b) {
        if (b&1) {
            ret += t;
            if (ret > mod_val) {
                ret -= mod_val;//直接取模慢很多
            }
        }
        t <<= 1;
        if (t > mod_val) {
            t -= mod_val;
        }
        b >>= 1;
    }
    return ret;
}

// 计算 ret = (x^n)%mod_val
LL pow_mod(LL x, LL n, LL mod_val)
{
    LL ret = 1;
    LL t = x%mod_val;
    while (n)
    {
        if (n&1) {
            ret = mult_mod(ret, t, mod_val);
        }
        t = mult_mod(t, t, mod_val);
        n >>= 1;
    }
    return ret;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值