AtCoder Beginner Contest 280 D-E

D - Factorial and Multiple

前置知识

n!中包含素因子p的个数为

cnt=k1pknnpk

例如:n!中包含的2的个数可以这么找:先找1~n中2的倍数的个数n2,再找1~n中4的倍数的个数n4,再......直到2k>n为止。

思路

先对k进行质因数分解,再二分n

Code

#include <bits/stdc++.h>
using namespace std;
#define _u_u_ ios::sync_with_stdio(false), cin.tie(nullptr)
#define cf int _o_o_;cin>>_o_o_;for (int Case = 1; Case <= _o_o_;Case++)
#define SZ(x) (int)(x.size())
inline void _A_A_();
signed main() {
    #ifdef LOCAL
    freopen("in.in", "r", stdin);
    #endif
    _u_u_;
    _A_A_();
    return 0;
}

#define int long long
const int mod = 1e9 + 7;
const int maxn = 1e12 + 10;
const int N = 210, M = 5010;
const int inf = 0x3f3f3f3f;

int qpow(int a, int b) {
    int res = 1;
    while (b) {
        if (b & 1) {
            res = res * a;
        }
        a = a * a;
        b >>=1;
    }
    return res;
}

vector<pair<int,int>> p;

bool check(int mid ) {
    for (auto x : p) {
        int temp = 0;
        for (int i = 1;qpow(x.first,i) <= mid;i++) {
            temp += mid / qpow(x.first, i);
        }
        if (temp < x.second) return 0;
    }
    return 1;
}

inline void _A_A_() {
    int k,t;
    cin >> k;
    t = k;
    for (int i = 2;i <= sqrt(k);i++) {
        if (t % i == 0) {
            p.push_back({i,0});
        }
        while (t % i == 0) {
            p.back().second++;
            t /= i;
        }
    }
    if (t != 1) {
        p.push_back({t,1});
    }
    int l = 1, r = maxn;
    while (l < r) {
        int mid = l + r  >> 1;
        if (check(mid)) {
            r = mid;
        }
        else {
            l = mid + 1;
        }
    }
    cout << l << "\n";
}

E - Critical Hit

状态表示

dp[i]表示当将怪物打到还剩i生命值时攻击的期望次数。

转移方程

dp[i]=(p100dp[i+2]+(1p100)dp[i+1]+1)modmod

编码的两种方法

这里将100在模mod下的逆元inv先求了出来,这样1-p/100就能表示为(100-p) * invp/100就能表示为p * inv

但是,无法得到正确答案。

inline void _A_A_() {
    int n, p;
    cin >> n >> p;
    int inv = qpow(100, mod - 2);
    dp[n] = 0;
    for (int i = n - 1;i >= 0;i -- ) {
        dp[i] = (p * inv * dp[i + 2] % mod + (100 - p) * inv * dp[i + 1] % mod + 1 + mod) % mod;
    }
    cout << dp[0] << "\n";
}

这里m表示p/100在模mod下的表示。这样1 - p/100就能表示为1 - m

这样答案正确!!!

inline void _A_A_() {
    int n, p;
    cin >> n >> p;
    int m = p * qpow(100, mod - 2) % mod;
    dp[n] = 0;
    for (int i = n - 1;i >= 0;i -- ) {
        dp[i] = (dp[i + 1] * (1 - m + mod) % mod + dp[i + 2] * m % mod + 1) % mod;
    }
    cout << dp[0] << "\n";
}
posted @   Uzhia  阅读(44)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示