• 牛客练习赛43-F(简单容斥)


    题目链接:https://ac.nowcoder.com/acm/contest/548/F

    题意:简化题意之后就是求[1,n]中不能被[2,m]中的数整除的数的个数。

    思路:简单容斥题,求[1,n]中不能被[2,m]中的数整除的数的个数,可以通过求能够被整除的数。

       首先,[2,m]中的合数肯定能由[2,m]中的素数的乘积来表示,所以我们仅需要考虑[1,n]中能由[2,m]中的素数整除的数的个数即可,记为sum。

       然后,我们知道[1,n]中能够被x整除的数的个数为n/x(向下整除)。

       then,如果按上一步计算的话,会出现重复计算的问题,这个时候就用到了容斥原理,若[2,m]有p个素数,分别为cnt[1]..cnt[p],那么这p个素数可以有(1<<p)-1个组合,记该组合中所有素数乘积为tmp,素数个数为num,则能被tmp整除的数有(n/tmp)个,若num为奇数,则sum加上(n/tmp),若为偶数,则sum减上(n/tmp),这样就解决了问题。还有本题要注意的一个小细节是若k==0,直接输出QAQ即可。

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 
     5 int T,m,cnt[10]={0,2,3,5,7,11,13,17,19};
     6 int M[25]={0,0,1,2,2,3,3,4,4,4,4,5,5,6,6,6,6,7,7,8,8};
     7 LL k,q,n,sum;
     8 
     9 int main(){
    10     scanf("%d",&T);
    11     while(T--){
    12         scanf("%lld%lld%lld%d",&k,&q,&n,&m);
    13         int p=M[m];
    14         sum=0;
    15         for(int i=1;i<(1<<p);++i){
    16             int num=0;
    17             LL tmp=1;
    18             for(int j=1;j<=p;++j)
    19                 if((1<<(j-1))&i){
    20                     ++num;
    21                     tmp*=cnt[j];
    22                 }
    23             if(num&1)
    24                 sum+=n/tmp;
    25             else
    26                 sum-=n/tmp;
    27         }
    28         sum=(n-sum)+k-1;
    29         if(sum>n) sum=n;
    30         if(k&&sum>=q) printf("Yes
    ");
    31         else printf("QAQ
    ");
    32     }
    33     return 0;
    34 }
  • 相关阅读:
    JS闭包
    css3 背景渐变
    css扩展技术:Less和Sass的区别
    HTML5 Canvas八大核心技术及其API用法
    HTML5新标签含义,用法及其与HTML4的区别
    当离散遇见连续
    素数测试
    概率采样问题
    二分查找及其变种
    C++与Java多态的区别
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/10664483.html
Copyright © 2020-2023  润新知