zoukankan      html  css  js  c++  java
  • 牛客练习赛52 C 烹饪(容斥+扩展欧几里得)

    来源:https://ac.nowcoder.com/acm/contest/1084/D
    思路来源:https://www.cnblogs.com/Morning-Glory/p/11521114.html

    题意

    n个数,从中选一些数,使得他们通过加减法能构成任意正整数(每个数可以使用无穷多个),问有多少种方案

    思路

    只要选中的数中,有两个数可以构成1,就可以构成任意的正整数了
    形式化的表示为选中的这一堆数中存在x,y使得(ax+by=1)
    根据扩展欧几里得,上式当且仅当(gcd(x,y)=1)的时候有解
    而一旦一些数中存在两个数互质,那么所有的数都互质
    所以我们只需要找到所有的非空子集,使得集合里的所有数互质即可

    设f[i]为gcd为i的子集个数
    (f[i]=gcd)((i,2i,3i,...))的子集个数(-f[2i]-f[3i]-...)
    而gcd为i的倍数的子集个数为(2^{所有i的倍数的数的个数}-1)
    答案即(f[1])

    代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<stack>
    #include<queue>
    #include<deque>
    #include<set>
    #include<vector>
    #include<map>
    #include<functional>
    #include<unordered_map>
        
    #define fst first
    #define sc second
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lc root<<1
    #define rc root<<1|1
    
    using namespace std;
    
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;
    
    const db eps = 1e-6;
    const int mod = 998244353;
    const int maxn = 5e5+100;
    const int maxm = 2e6+100;
    const int inf = 0x3f3f3f3f;
    const db pi = acos(-1.0);
    
    int n,m;
    int num[maxn];
    ll po[maxn];
    ll f[maxn];
    int a[maxn];
    int main(){
        scanf("%d", &n);
        for(int i = 1; i <= n; i++){
            scanf("%d", &a[i]);
            for(int j = 1; j<=a[i]; j++){
                if(a[i]%j==0){num[j]++;}
            }
        }
        po[0]=1;
        for(int i = 1; i <= 3000; i++)po[i]=(po[i-1]*2)%mod;
        for(int i = 3000; i >= 1; i--){
            f[i]=(po[num[i]]+mod-1)%mod;
            for(int j = 2; j*i<=3000; j++){
                f[i]=(f[i]+mod-f[j*i])%mod;
            }
        }
        printf("%lld",f[1]%mod);
        return 0;
    }
    
  • 相关阅读:
    C 语言 静态库和动态库的创建和应用
    C++ 中英文术语对照
    下午
    [转]内核 do_fork 函数源代码浅析
    关于C#反射机制,自己写的
    获取字符串中数字
    关于C#反射机制,来源于网络
    关于 Nhinernate 的one to one(转载)
    鼠标坐标的记录
    关于C#中hibernate.cfg.xml动态加载问题
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/11528381.html
Copyright © 2011-2022 走看看