• UVA 10325 lottery 容斥原理


    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=15&problem=1266&mosmsg=Submission+received+with+ID+9619336 

    题意: 给定 n,m  和 m 个数 ,求  1~n 中 不能  能被 m个数中的任意 一个数整除 的个数

    题解: 

    首先明白对于集合[1,n]内能被a整除的数的个数为n/a,既能被a整除又能被b整除的数的个数为n/lcm(a,b)(a,b的最小公倍数);

    容斥原理地简单应用。先找出1...n - 1内能被集合M中任意一个元素整除的个数,再减去能被集合中任意两个整除的个数,即能被它们俩的最小公倍数整除的个数,因为这部分被计算了两次,然后又加上三个时候的个数,然后又减去四个时候的倍数...直接枚举状态0...(1<<m),然后判断状态内涵几个集合元素,然后计算lcm和能被整除的个数,最后判断下集合元素的个数为奇还是偶,奇加偶减。这里回溯搜索M元素的组合也行

      

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<set>
     7 #include<map>
     8 #include<queue>
     9 #include<vector>
    10 #include<string>
    11 #define inf 0x7fffffff
    12 #define maxn 60000
    13 #define CL(a,b) memset(a,b,sizeof(a))
    14 #define  ll  long long
    15 using namespace std;
    16  ll n , m  ;
    17  ll a[20] ;
    18  ll gcd(ll a,ll b)
    19  {
    20 
    21      if(b == 0return a;
    22 
    23      return gcd(b,a%b) ;
    24 
    25  }
    26  ll lcm(ll a,ll b)
    27  {
    28       ll d = gcd(a,b) ;
    29 
    30       return a*b/d ;
    31  }
    32  int main()
    33  {
    34       int i  ;
    35     while(scanf("%lld%lld",&n,&m)!=EOF)
    36     {
    37         ll  ans= 0 ;
    38         for(i = 0 ;i < m;i++ )
    39         {
    40             scanf("%lld",&a[i]) ;
    41 
    42         }
    43 
    44 
    45          ll  sum =  0 ;
    46         for(ll msk = 1 ; msk < (1<< m); msk++)// 所有的情况
    47         {
    48 
    49 
    50             ll mul = 1;
    51 
    52             ll bits = 0 ;
    53 
    54             for(int j = 0 ; j < m;j++)
    55             {
    56 
    57 
    58                 if(msk & (1 << j))
    59                 {
    60 
    61                     bits ++ ;
    62                     mul = lcm(mul, a[j]) ;
    63                     if(mul > n)break ;
    64 
    65 
    66                 }
    67 
    68 
    69 
    70 
    71             }
    72 
    73             if(mul > n) continue  ;
    74 
    75             ll cur =  n/mul  ;
    76 
    77 
    78             if(bits & 1 )
    79             {
    80                 sum += cur ;
    81             }
    82             else sum -= cur ;
    83 
    84         }
    85 
    86 
    87         printf("%lld\n",n - sum ) ;
    88 
    89 
    90 
    91     }
    92 
    93  }
  • 相关阅读:
    udp和tcp
    以查询代替临时变量
    memcached内存管理
    设计模式适配器模式
    排序算法
    防止表单重复提交
    php的引用
    按位与,按位异或,按位取反
    git常用操作
    http
  • 原文地址:https://www.cnblogs.com/acSzz/p/2775937.html
Copyright © 2020-2023  润新知