8的倍数——题解(容斥原理)

10人阅读 评论(0) 收藏 举报
分类:

题目描述


小x最近对数字8很感兴趣,有8进制,2008奥运会之类的。
现在小x想知道,在[x,y]区间里,有多少个数能被8整除。
小y觉得题目太简单,于是给出n个其他数,问在[x,y]区间里,有多少个数能被8整除且不能被这n个数整除


分析

啊啊啊啊啊,一道很水的容斥原理啦QWQ,枚举出这个n个数所有和8的lcm的情况,奇减偶加,这道题最麻烦的地方在于枚举出所有的情况,看那些超级大佬都是dfs枚举情况,蒟蒻的我实在太菜(lan)了,就用二进制枚举情况咯!!!

//By Bibi
///                 .-~~~~~~~~~-._       _.-~~~~~~~~~-.
///             __.'              ~.   .~              `.__
///           .'//                  \./                  \\`.
///        .'//                     |                     \\`.
///       .'// .-~"""""""~~~~-._     |     _,-~~~~"""""""~-. \\`.
///     .'//.-"                 `-.  |  .-'                 "-.\\`.
///   .'//______.============-..   \ | /   ..-============.______\\`.
/// .'______________________________\|/______________________________`.
#include<bits/stdc++.h>
#define rep(i,a,b) for(long long i=a;i<=b;++i)
#define dep(i,a,b) for(long long i=a;i>=b;--i)
using namespace std;
const long long MAXN=20;
typedef long long ll;
ll read(){
    ll sum=0,flag=1;
    char c;
    for(;c<'0'||c>'9';c=getchar())if(c=='-') flag=-1;
    for(;c>='0'&&c<='9';c=getchar())sum=(sum<<1)+(sum<<3)+c-'0';
    return sum*flag;
} 
ll n;
ll a[MAXN];
ll ans1,ans2;
ll x,y;
ll gcd(ll a,ll b){
    return b? gcd(b,a%b):a;
}
void init(){
    n=read();
    rep(i,0,n-1) a[i]=read();
    x=read();y=read();
}
void work1(){
    rep(i,0,(1<<n)-1){
        ll tot=0,true_num=8;
        rep(j,0,n-1){
            if(i&(1<<j)){
                true_num*=a[j]/gcd(true_num,a[j]);
                if(true_num>x-1) break;
                tot++;
            }
        }
        if(tot&1) ans1-=(x-1)/true_num;
        else ans1+=(x-1)/true_num;
    }
}
void work2(){
    rep(i,0,(1<<n)-1){
        ll tot=0,true_num=8;
        rep(j,0,n-1){
            if(i&(1<<j)){
                true_num*=a[j]/gcd(true_num,a[j]);
                if(true_num>y) break;
                tot++;
            }
        }
        if(tot&1) ans2-=(y)/true_num;
        else ans2+=(y)/true_num;
    }
}
int main(){
    init();
    work1();
    work2();
    printf("%lld\n",ans2-ans1);
    return 0;
}
查看评论

ACM-容斥原理

去重复
  • u011787119
  • u011787119
  • 2014年10月21日 22:46
  • 1863

51Nod 1284 2 3 5 7的倍数

给出一个数N,求1至N中,有多少个数不是2 3 5 7的倍数。 例如N = 10,只有1不是2 3 5 7的倍数。 Input 输入1个数N(1 ...
  • iamldy
  • iamldy
  • 2017年06月29日 01:01
  • 292

2、3、4、5、7、8、9、11、13、25、125的倍数的特征

 2的倍数特征: 整数末尾是0、2、4、6、8、……的数。 3的倍数特征: 整数各个位数字和是3的倍数。例如:3、6、9、12、15、18……、156…… 4的倍数特征: 整数末两...
  • slx_391987
  • slx_391987
  • 2014年09月05日 08:46
  • 3652

将某个数字上调为8的倍数

#define ALIGN 8 (数字+(ALIGN-1))&~(ALIGN-1)  
  • jiang1013nan
  • jiang1013nan
  • 2010年08月11日 16:44
  • 349

算法中的容斥原理

翻译:vici@cust 对容斥原理的描述 容斥原理是一种重要的组合数学方法,可以让你求解任意大小的集合,或者计算复合事件的概率。 描述        容斥原理可以描述如下:          要计算...
  • xianglunxi
  • xianglunxi
  • 2013年07月12日 12:34
  • 6741

2 3 5 7的倍数 --容斥原理

给出一个数N,求1至N中,有多少个数不是2 3 5 7的倍数。 例如N = 10,只有1不是2 3 5 7的倍数。 Input 输入1个数N(1 Output 输出不是2 3 5 7的倍数...
  • JingleLiA
  • JingleLiA
  • 2018年02月02日 17:54
  • 134

<stl>将bytes上调至8的倍数

在源码剖析>>的空间配置一章的二级配置器中,有如下一段源代码,功能是将bytes上调至8的倍数。 enum{_ALIGN=8}; //小型区块的上调边界 private: static size_t ...
  • lijun538
  • lijun538
  • 2015年10月17日 11:54
  • 661

错排公式的容斥推导

问题提出:n封不同的信对应n个不同的信箱,问都装错信封的方法有多少种?...
  • ACdreamers
  • ACdreamers
  • 2012年11月07日 21:30
  • 2302

STL的内存池的设计源码分析和体会

STL的内存池的设计源码分析和体会
  • billiejeannotmylover
  • billiejeannotmylover
  • 2014年01月14日 18:29
  • 958

组合数学:容斥原理及其应用

容斥原理 例题:{1,,2...n}的排列i1i2..in计数,其中1不在第一个位置 当k不在第一个位置的时候,第一个位置又n-1种可能,后面所有位置排列为(n-1)! 也可以用当k在第一个位置的...
  • hhy518518
  • hhy518518
  • 2015年07月27日 22:53
  • 534
    个人资料
    持之以恒
    等级:
    访问量: 6096
    积分: 705
    排名: 6万+
    友情链接
    最新评论