zoukankan      html  css  js  c++  java
  • [CF900D] Unusual Sequences

    [CF900D] Unusual Sequences - 组合,容斥,dp

    Description

    输入x,y,求有多少个数列满足其gcd为x,和为y。

    Solution

    令 m=y/x,则答案等于 gcd=1,sum=m 的数列个数

    (f[i]) 表示 sum=i 的数列个数

    (g[i]) 表示 sum|i 的数列个数

    (g[i]=sum_{d|i} f[d])

    (g[i]) 是容易求出的,根据隔板法,(g[i]=2^{i-1})

    (f[i]) 有两种方法,一种是手动容斥,一种是莫比乌斯反演

    这里我们用手动容斥,枚举 gcd=d,然后删去 f(n/d)

    (f[i] = g[i] - sum_{d|i, d<i} f[i/d])

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    const int mod = 1e9 + 7;
    
    namespace math_mod
    {
        int c__[5005][5005], fac__[3000005];
    
        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 fac(int p)
        {
            if (p <= 3000000)
                return fac__[p];
            if (p == 0)
                return 1;
            return p * fac(p - 1) % mod;
        }
    
        int __fac(int p)
        {
            return fac(p);
        }
    
        int ncr(int n, int r)
        {
            if (r < 0 || r > n)
                return 0;
            return fac(n) * inv(fac(r)) % mod * inv(fac(n - r)) % mod;
        }
    
        void math_presolve()
        {
            fac__[0] = 1;
            for (int i = 1; i <= 3000000; i++)
            {
                fac__[i] = fac__[i - 1] * i % mod;
            }
            for (int i = 0; i <= 5000; i++)
            {
                c__[i][0] = c__[i][i] = 1;
                for (int j = 1; j < i; j++)
                    c__[i][j] = c__[i - 1][j] + c__[i - 1][j - 1], c__[i][j] %= mod;
            }
        }
    
        int __c(int n, int r)
        {
            if (r < 0 || r > n)
                return 0;
            if (n > 5000)
                return ncr(n, r);
            return c__[n][r];
        }
    }
    
    using namespace math_mod;
    int m;
    map<int, int> f;
    
    int solve(int x)
    {
        if (f.find(x) != f.end())   
            return f[x];
        int ans = qpow(2, x - 1);
        vector<int> fac;
        for (int i = 2; i * i <= x; i++)
            if (x % i == 0)
            {
                fac.push_back(i);
                if (i * i != x)
                    fac.push_back(x / i);
            }
        fac.push_back(1);
        for (auto i : fac)
            ans = (ans - solve(i) + mod) % mod;
        return f[x] = ans;
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
        int x, y;
        cin >> x >> y;
        m = y / x;
        f[1] = 1;
        if (y % x)
            cout << 0 << endl;
        else
            cout << solve(m) << endl;
    }
    
  • 相关阅读:
    鹰牌陶瓷签约亿客CRM系统 建材行业进入CRM时代
    CRM成为大数据落地的关键
    客户流失了怎么办?
    亿客CRM研发公司简介
    CRM销售管理软件让销售管理成为企业的助力
    CRM帮助企业的营销管理
    浅析移动CRM的客户价值细分
    CRM规划和执行战略
    信息化的先锋CRM
    SaaS的应用将弱化大小企业间竞争差距
  • 原文地址:https://www.cnblogs.com/mollnn/p/14486142.html
Copyright © 2011-2022 走看看