kuangbin数学训练1

LightOJ - 1078 Integer Divisibility

思路

博弈
先手必胜: 可以走到必败状态
先手必败: 无论如何也走不到必败状态

该题,模拟一下就知道

  1. 若Alice先手的情况,则n%3 == 1 是先手必败状态
  2. 若Bob先手的情况,则n%3 == 0 是先手必败状态

代码

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

int main() {
    int T;
    scanf("%d", &T);
    int id = 0;
    while(T --) {
        int n;
        string name;
        string ans;
        cin >> n >> name;
        if(name == "Alice") {
            if(n % 3 == 1) {
                ans = "Bob";
            }
            else
                ans = "Alice";
        }
        else {
            if(n % 3 == 0) {
                ans = "Alice";
            }
            else
                ans = "Bob";
        }
        printf("Case %d: %s\n", ++id, ans.c_str());
    }
    return 0;
}

LightOJ - 1124 Cricket Ranking

思路

和Dev的鲜花类似
唯一不同的是:
鲜花是可以取【0,A[i]】
这里是[l,r]
偏移一下就可以了
[l, r] -> [0, r-l], 同时N也要减去l

代码

#include<iostream>
#include<cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 20, mod = 100000007;
LL A[N];
LL n, m;
int down;

LL qmi(LL a, LL b, int mod) {
    LL res = 1;
    while(b) {
        if(b & 1)
            res = (LL)res * a % mod;
        a = (LL)a * a % mod;
        b >>= 1;
    }

    return res;
}
LL C(LL a, LL b) {
    if(a < b)
        return 0;
    int up = 1;
    for (int i = a; i > a - b; i --) {
        up = (LL)i % mod * up % mod;
    }

    return (LL)up * down % mod;
}

int main() {
    int T;
    int id = 0;
    scanf("%d", &T);
    while(T --) {
        scanf("%lld%lld", &n, &m);
        for (int i = 0; i < n; i ++){
            LL l, r;
            scanf("%lld%lld", &l, &r);
            r -= l;
            m -= l;
            A[i] = r;
        }

        // 预处理1/((n-1)!)
        down = 1;
        for (int i = 1; i <= n - 1; i ++)
            down = (LL)i * down % mod;
        down = qmi(down, mod - 2, mod);

        LL res = 0;
        for (int i = 0; i < 1 << n; i ++) {
            int sign = 1;
            LL a = m + n - 1, b = n - 1;
            for (int j = 0; j < n; j ++)
                if(i >> j & 1) {
                    sign *= -1;
                    a -= A[j] + 1;
                }
            res = (res + C(a, b) * sign) % mod;
        }

        printf("Case %d: %lld\n", ++id, (res + mod) % mod);
    }

    return 0;
}

LightOJ - 1144 Ray Gun

思路

∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = 1 ] \sum_{i=1}^n \sum_{j=1}^{m}[gcd(i,j)=1] i=1nj=1m[gcd(i,j)=1]

莫比乌斯函数,容斥原理, 整除分块

代码

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 1e6 + 10;
int primes[N];
bool st[N];
int cnt;
int mu[N];
int sum[N];

void moblus()
{
    memset(st, false, sizeof st);
    mu[1] = 1;
    cnt = 0;
    for (int i = 2; i < N; i ++) {
        if(!st[i]) {
            primes[cnt++] = i;
            mu[i] = -1;
        }

        for (int j = 0; primes[j] * i < N; j ++){
            int t = primes[j] * i;
            st[t] = true;
            if(i % primes[j] == 0) {
                mu[t] = 0;
                break;
            }
            mu[t] = mu[i] * -1;
        }
    }

    for (int i = 1; i < N; i ++) {
        sum[i] = sum[i - 1] + mu[i];
    }
}

int main() {
    moblus();

    int T;
    scanf("%d", &T);
    int id = 0;
    while(T --) {
        long long n, m;
        scanf("%lld%lld", &n, &m);
        if(n > m)
            swap(n, m);
        long long res = 0;
        for (long long l = 1, r; l <= n; l = r + 1) {
            r = min(n, min(n / (n / l), m / (m / l)));
            res += (sum[r] - sum[l - 1]) * (long long)(n / l) * (m / l);
        }

        if(n)
            res++;
        if(m) 
            res ++;
        printf("Case %d: %lld\n", ++id, res);
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值