zoukankan      html  css  js  c++  java
  • #422 Div2 D

    #422 Div2 D

    题意

    假设有 n 个人比赛,每次比赛进行分组,每组人数必须相同,如果一组有 x 人,则那一组要比赛 $ frac{x * (x - 1)}{2}$次,最终一人获胜,其它人淘汰,不同回合的 x 可以不同,设最终经过 f(n) 次比赛比赛结束(产生冠军)。给出 t, l, r 求 (t^0*f(l)+t^1*f(l+1)+...+t^{r-l}*f(r))

    分析

    通过测试几组数据可以发现,分的组越多,总比赛次数越少,那么就要 x 尽可能的小,所以对于参赛的 n 个人, n 的最小质因子 k 为每组的人数,如果 n 为素数,(f(n)=frac{n * (n - 1)} 2),否则 (f(n)=f(frac n k)+frac n k * f(k)),。

    code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int MAXN = 5e6 + 5;
    const int INF = 2e9 + 1;
    const ll MOD = 1e9 + 7;
    ll dp[MAXN];
    int is_prime[MAXN];
    vector<int> prime;
    int main() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        for(int i = 2; i < MAXN; i++) {
            if(!is_prime[i]) {
                prime.push_back(i);
                for(ll j = 1LL * i * i; j < MAXN; j += i) {
                    is_prime[j] = 1;
                }
            }
        }
        ll t;
        int l, r;
        cin >> t >> l >> r;
        for(int i = 2; i <= r; i++) {
            if(!is_prime[i]) {
                dp[i] = 1LL * i * (i - 1) / 2 % MOD;
            } else {
                for(auto j : prime) {
                    if(i % j == 0) {
                        dp[i] = (dp[i / j] + 1LL * i / j * dp[j]) % MOD;
                        break;
                    }
                }
            }
        }
        ll x = 1, ans = 0;
        for(int i = l; i <= r; i++) {
            ans = (ans + x * dp[i]) % MOD;
            x = (x * t) % MOD;
        }
        cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    Java实现 LeetCode 211 添加与搜索单词
    跨平台Unicode与UTF8互转代码
    C++转换unicode utf-8 gb2312编码
    c++ ANSI、UNICODE、UTF8互转
    Visual C++ unicode and utf8 转换
    Unicode和UTF-8的关系
    boost uuid 学习笔记
    boost uuid
    Darwin Streaming server 的 Task 类
    VS2010下编译安装DarwinStreamingServer5.5.5
  • 原文地址:https://www.cnblogs.com/ftae/p/7125981.html
Copyright © 2011-2022 走看看