zoukankan      html  css  js  c++  java
  • Codeforces 900D Unusual Sequences

    题目链接

    https://codeforces.com/contest/900/problem/D

    题目大意

    给你 X 、Y,让你构造一个序列a满足 gcd(a1, a2, ..., an) = x 并且 $sum ^{n}_{i=1}a_{i}=y$

    求满足条件的序列个数

    解题思路

    很显然当 Y % X != 0 时是无法构造出系列满足条件的

    当 Y % X == 0 时,我们可以将条件建转换一下

    即构造序列a满足gcd(a1, a2, ..., an) = 1 并且  $sum ^{n}_{i=1}a_{i}=y/x$

    那么如果只看条件②,我们用隔板法可以得到的构造方案为 $sum ^{n}_{i=1}a_{i}=y/x$  参见这里

    然后我们再看条件①,因为构造出来的部分答案可能会改变gcd,所以我们只要再把改变gcd的情况减掉就可以了

    举个栗子: X = 3 , Y = 12  ,  那么改变条件之后 X = 1 , Y = 4。假设 solve(y / x) 得到的是当 gcd = x , sum = y 的构造方案

    那么这个栗子的答案就为 solve(4 / 1)  - solve(4 / 2)  

    AC_Coder

    #include<bits/stdc++.h>
    #define rep(i,a,n) for (int i=a;i<=n;i++)
    #define int long long
    #define ll long long 
    #define MOD 1000000007
    using namespace std;
    ll pow_mod(ll x , ll n , ll mod)
    {
        ll res = 1;
        while(n)
        {
            if(n & 1) res = res * x % mod;
            x = x * x % mod;
            n >>= 1;
        }
        return res;
    }
    const int N = 2e5 + 10;
    unordered_map<int , int>vis;
    int dfs(int n)
    {
        if(n == 1) return 1;
        if(vis[n]) return vis[n];
        vis[n] = pow_mod(2 , n - 1 , MOD) - 1;
        for(int i = 2 ; i * i <= n ; i ++)
        {
            if(n % i == 0)
            {
                vis[n] = (vis[n] - dfs(n / i) + MOD) % MOD;
                if(i * i != n) 
                vis[n] = (vis[n] - dfs(i) + MOD) % MOD;
            }    
        }    
        return vis[n];
    } 
    signed main()
    {
        int x , y;
        cin >> x >> y;
        if(y % x) return cout << 0 << '
    ' , 0;
        int ans = dfs(y / x);
        cout << ans << '
    ';
        return 0;
    }
    凡所不能将我击倒的,都将使我更加强大
  • 相关阅读:
    sql常用函数
    sql数据库查询
    数据库增删改查
    数据库基本概念
    C#总结
    C#结构体
    C#常用函数类
    初识函数
    C#冒泡排序 折半查找
    12月27日笔记
  • 原文地址:https://www.cnblogs.com/StarRoadTang/p/13026105.html
Copyright © 2011-2022 走看看