牛客练习赛68-B-牛牛的算术-取模+逆元+思维? 2020/9/1

在这里插入图片描述
题目连接: https://ac.nowcoder.com/acm/contest/7079/B

第一种方法: 多个前缀和, 通过i = n-1来得到i = n的情况, 稍显复杂, 公式请自行推导.
第二种方法: 化简, 将上式j, k全部替换成i,
先看最内层: k从 1 到 j , 而i, j不变, 用a(n) = n 的求和公式, 去掉∑之后变成:

∏ ∑ i * j * (1 + j) * j / 2  = ∏ ∑ i * (j ^ 2 + j ^ 3) /2;  

然后再去最后一个∑, j 从 1 到 i, 而 i 不变, 这个地方用到的是
a(n) = n ^ 2 和 a(n) = n ^ 3的求和公式(点击跳转),
最后化简得到 :
 从大佬那里拿来的, 滑稽

给的n <= 10 ^ 10 ^ 5, 非常大, 显然, n >= 某个值的时候, 式子 == 0 然后再乘啥东西也是0了, 打表flag记录这个值, 就行了.

注意:

  1. 乘法逆元, 我将4个式子进行通分后, 直接乘24的逆元方便很多.
  2. 输入n很大, 10^5位的数字, 要用字符串, 不能用long long啊
  3. 注意中途不能爆long long! 我改了好久bug, 万万没想到是Pow函数爆了!!! (((φ(◎ロ◎;)φ)))

ps: 数列求和

code:


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int mod = 199999;
int n;
ll ijk[200000];
char s[500010];
ll Pow(ll x, int n) {
    ll ans = 1;
    for (int i = 1; i <= n; i++) {
        ans *= x;
        ans %= mod;
    }
    return ans;
}
ll qmi(ll a, ll b, ll p) {
    ll res = 1;
    while (b) {
        if (b & 1) res = res * a % p;
        a = a * a % p;
        b >>= 1;
    }
    return res;
}
int main() {
    cin >> n;
    getchar();
    int flag;
    ijk[0] = 1;
    for (int i = 1; i < 2000000; i++) {
        ijk[i] = ijk[i - 1] * ((Pow(i, 5) * 3 % mod + Pow(i, 4) * 10 % mod + Pow(i, 3) * 9 % mod + Pow(i, 2) * 2 % mod) * qmi(24, mod - 2, mod) % mod ) % mod;
        //乘法逆元
            cout << i << ' ' << ijk[i] << '\n';
        if (ijk[i] == 0) {
            flag = i;
            break;
        }
    }
    //cout << flag << '\n';
    while (n--) {
        //scanf_s("%s", s, 100000); //VS
        //scanf("%s", s);
        //cout << flag << '\n';
        int len = strlen(s);
        if (len > 5)
            cout << "0\n";
        else {
            int x = 0;
            for (int i = 0; i < len; i++) {
                x = x * 10 + (s[i] - '0');
            }
            //cout << x << "  s ";
            if (x >= flag) {
                cout << '0' << '\n';
            }
            else
                cout << ijk[x] << '\n';
        }
    }
    return 0;
}

2020-9-1, 每一天都有点意思呢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值