zoukankan      html  css  js  c++  java
  • [CF1359E] Modular Stability

    Description

    求有多少单调递增的数列 (a_1,a_2,...,a_n),对于任意一个 (x) 都满足,对于任意一种排列 (p),都有 (x mod a_{p_1} mod a_{p_2} mod ... mod a_{p_n} = Const) 成立。

    Solution

    首先考虑只有两个数的情况,(x mod a mod b = x mod b mod a) 成立当且仅当 (a,b) 中大的是小的的倍数。

    猜想序列中任何一个数必须是最小数的倍数。充分性是显然的。

    假设有一个数不是最小数的倍数,那么将其他是倍数的数打成一个整体,一些是倍数的数的连续处理本质上等价于对最小的那个数取模,因此转化为上面只有两个数的情况。这样就反证了一个数不是最小数的倍数的情况是不存在的,不止一个数的情况同理。

    我们枚举序列中的最小数 (i),那么它的倍数有 ([n/i]-1) 个,我们要从这些中选出 (k-1) 个,暴力计算组合数即可。

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 1000005;
    const int mod = 998244353;
    
    vector<int> frac(N + 2);
    
    void presolve()
    {
        frac[0] = 1;
        for (int i = 1; i <= N; i++)
            frac[i] = frac[i - 1] * i % mod;
    }
    
    int qpow(int p, int q)
    {
        return (q & 1 ? p : 1) * (q ? qpow(p * p % mod, q / 2) : 1) % mod;
    }
    
    int inv(int p)
    {
        return qpow(p, mod - 2);
    }
    
    int ncr(int n, int m)
    {
        if (n < 0 || m < 0 || n < m)
            return 0;
        return frac[n] * inv(frac[m]) % mod * inv(frac[n - m]) % mod;
    }
    
    signed main()
    {
        int n, k;
        cin >> n >> k;
        int ans = 0;
        presolve();
        for (int i = 1; i <= n; i++)
        {
            ans += ncr(n / i - 1, k - 1);
            ans %= mod;
        }
        cout << ans << endl;
    }
    
  • 相关阅读:
    01-2制作U盘启动盘--装机助理工具
    01-1制作U盘启动盘--大白菜超级U盘启动盘制作工具
    计算机操作系统
    设置电脑系统密码以及桌面密码
    bios文字解释
    Word基本文档字体设置
    Ctrl/Alt 快捷键
    Windows键
    Laravel 5.2 四、.env 文件与模型操作
    Laravel 5.2 三、中间件、视图与 Blade 模板引擎
  • 原文地址:https://www.cnblogs.com/mollnn/p/14116937.html
Copyright © 2011-2022 走看看