zoukankan      html  css  js  c++  java
  • 烹饪 [容斥]

    烹饪

    题目描述见链接 .


    color{red}{正解部分}

    {bi}{b_i} 中存在能够 凑出 11 的数字, 则可以凑出所有数字 .

    于是考虑哪些数字可以凑出 11,
    22 个数字 x,yx,y, ax+by=1ax + by = 1 有解的前提是 gcd(i,j)=1gcd(i, j) = 1, 推广到更多数字 kiai=1sum k_ia_i = 1 有解的前提是 gcd(ki)=1gcd(k_i)=1.

    于是 题目转化 为: 求出有多少种选数方法, 满足 gcd(b1,b2...bm)=1gcd(b_1, b_2...b_m)=1 .

    考虑 容斥, 设 F[i]F[i] 表示满足以 iigcdgcd 的选出序列的个数,
    F[i]F[i] 初值2cnti12^{cnt_i}-1, 减去所有 F[ki,kZ]F[ki, k in Z] 即可得到 gcd=igcd = i 的序列数, 最后 F[1]F[1] 即为答案 .


    color{red}{实现部分}

    #include<bits/stdc++.h>
    #define reg register
    
    int read(){
            char c;
            int s = 0, flag = 1;
            while((c=getchar()) && !isdigit(c))
                    if(c == '-'){ flag = -1, c = getchar(); break ; }
            while(isdigit(c)) s = s*10 + c-'0', c = getchar();
            return s * flag;
    }
    
    const int maxn = 3005;
    const int mod = 998244353;
    
    int N;
    int Max_v;
    int A[maxn];
    int F[maxn];
    int pw[maxn];
    
    int main(){
            N = read(); pw[0] = 1;
            for(reg int i = 1; i < maxn; i ++) pw[i] = 2ll*pw[i-1] % mod;
            for(reg int i = 1; i <= N; i ++) A[i] = read(), Max_v = std::max(Max_v, A[i]);
            for(reg int i = Max_v; i >= 1; i --){
                    int cnt = 0;
                    for(reg int j = 1; j <= N; j ++) cnt += (A[j]%i == 0);
                    F[i] = pw[cnt] - 1;
                    for(reg int j = 2*i; j <= Max_v; j += i) F[i] -= F[j], F[i] = (F[i]%mod+mod)%mod;
            }
            printf("%d
    ", F[1]);
            return 0;
    }
    
  • 相关阅读:
    redis:高可用分析
    mysql:explain分析sql
    python中注意事项(更新)
    jupyter使用小技巧(更新)
    Jupyter中的快捷键
    Excel制作甘特图
    Vim编辑器常用命令
    Mysql主从
    常用MySql命令
    进程与线程的一个简单解释
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822444.html
Copyright © 2011-2022 走看看