• CF1097D Makoto and a Blackboard 积性函数、概率期望、DP


    传送门


    比赛秒写完ABC结果不会D……最后C还fst了qwq

    首先可以想到一个约数个数(^2)乘上(K)的暴力DP,但是显然会被卡

    (10^{15})范围内因数最多的数是(978217616376000=2^6 imes 3^4 imes 5^3 imes 7^2 imes 11 imes 13 imes 17 imes 19 imes 23 imes 29),它有(26880)个因数

    但是不难发现:在我们的答案中参与计算的只有约数个数函数和约数和函数。它们都是传统的积性函数。这给我们一些启示:可以考虑分解质因数然后DP。

    考虑对一个数(x=p^k)进行(DP),设(f_{i,j})表示初始数字为(p^j)、做(i)轮操作的期望值,转移为(f_{i,j} = frac{sumlimits_{k=0} ^ j f_{i-1,k}}{j+1}),使用前缀和优化转移。最后将所有质因数得到的答案乘起来就是最后的答案。

    #include<bits/stdc++.h>
    #define int long long
    //This code is written by Itst
    using namespace std;
    
    inline int read(){
        int a = 0;
        char c = getchar();
        bool f = 0;
        while(!isdigit(c) && c != EOF){
            if(c == '-')
                f = 1;
            c = getchar();
        }
        if(c == EOF)
            exit(0);
        while(isdigit(c)){
            a = a * 10 + c - 48;
            c = getchar();
        }
        return f ? -a : a;
    }
    
    const int MOD = 1e9 + 7;
    int dp[50][10010] , inv[52];
    
    inline int poww(int a , int b){
        int times = 1;
        while(b){
            if(b & 1)
                times = times * a % MOD;
            a = a * a % MOD;
            b >>= 1;
        }
        return times;
    }
    
    signed main(){
        for(int i = 1 ; i <= 51 ; ++i)
            inv[i] = poww(i , MOD - 2);
        int N = read() , K = read() , ans = 1;
        for(int i = 2 ; i * i <= N ; ++i)
            if(N % i == 0){
                int cnt = 0;
                while(N % i == 0){
                    ++cnt;
                    N /= i;
                }
                dp[0][0] = 1;
                int tms = i;
                for(int j = 1 ; j <= cnt ; ++j , tms = tms * i % MOD)
                    dp[j][0] = (dp[j - 1][0] + tms) % MOD;
                for(int j = 1 ; j <= K ; ++j){
                    dp[0][j] = 1;
                    for(int k = 1 ; k <= cnt ; ++k)
                        dp[k][j] = (dp[k][j - 1] * inv[k + 1] + dp[k - 1][j]) % MOD;
                }
                ans = ans * (dp[cnt][K] - dp[cnt - 1][K] + MOD) % MOD;
            }
        if(N != 1)
            ans = ans * ((poww(poww(2 , K) , MOD - 2) * (N % MOD) + MOD + 1 - (poww(poww(2 , K) , MOD - 2))) % MOD) % MOD;
        cout << ans;
        return 0;
    }
    
  • 相关阅读:
    #研发中间件介绍#定时任务调度与管理JobCenter
    分享一个分布式定时任务系统 ( python)
    APScheduler + Gearman 构建分布式定时任务调度-std1984-ITPUB博客
    分布式缓存的一起问题 – 后端技术 by Tim Yang
    新兵训练营系列课程——Feed架构介绍
    Mysql分库分表方案
    可扩展性设计之数据切分
    你的数据库数据量上亿,为了提高效率,要分库还是分表?具体怎么做
    58同城mysql分库分表实践-沈剑
    可动态扩展的分库分表策略浅谈
  • 原文地址:https://www.cnblogs.com/Itst/p/10235505.html
Copyright © 2020-2023  润新知