zoukankan      html  css  js  c++  java
  • 【数论】【容斥原理】八

    题目

    题目描述

    八是个很有趣的数字啊。八=发,八八=爸爸,88=拜拜。当然最有趣的还是8用二进制表示是1000。怎么样,有趣吧。当然题目和这些都没有关系。 某个人很无聊,他想找出[a,b]中能被8整除却不能被其他一些数整除的数。

    输入

    第一行一个数n,代表不能被整除的数的个数。 第二行n个数,中间用空格隔开。 第三行两个数a,b,中间一个空格。 a < =b < =1000000000

    输出

    一个整数,为[a,b]间能被8整除却不能被那n个数整除的数的个数。

    样例输入

    3
    7764 6082 462
    2166 53442

    样例输出

    6378

    提示

    对于30%的数据, 1 ≤n ≤5,1 ≤a ≤ b ≤ 100000。
    对于100%的数据,1 ≤ n ≤15,1 ≤ a ≤ b ≤ 10^9,N个数全都小于等于10000大于等于1。

    思路

    一看就能想到是容斥原理,首先,怎么算区间[a,b]中p的倍数的个数呢?
    首先,算出区间[1,b]的p倍数的个数很简单:即可,为高斯取整,即下取整。
    所以,要算[a,b]中p的倍数的个数,直接用[1,b]中p倍数的个数减去[1,a)中p的倍数即可。即:b/p-(a-1)/p,注意,这里不能算[1,a],因为a有可能也是p的倍数,如果算[1,a]就算不到a了。

    然后就要解决容斥的问题了,设U为区间[a,b]中所有的整数,E为U中所有8的倍数,Ai为U中所有num[i]倍数(num[i]为题目给出的第i个不想被整除的数)发现,我们要求的就是:
    如果你看不懂∩和∪,请看这张图:

    假设圆c1和c2分别代表集合C1,C2,则:
    C1∩C2=蓝色围起来的部分
    C1∪C2=红色围起来的部分

    好了,这样的话就不难明白了(你可以自己画一个图看看)。

    最后还有一个很重要的地方,同时能被num[1],num[2],…,num[N]整除的数不一定是num[1]·num[2]·…·num[N]的倍数,应该是lcm(num[1],num[2],…,num[N])的倍数

    代码

    怎么实现呢?容斥原理嘛,加加减减,如果不明白容斥原理就自己百度吧,反正我是用dfs实现的,我不明白怎么用循环弄,因为你的循环次数都是不确定的,要乘的num[i]也是不确定的。所以就用dfs了,如果你一意想要用循环,百度吧……

    #include<cstdio>
    #include<iostream>
    using namespace std;
    #define LL long long
    
    #define MAXN 20
    LL N,a,b,ans;
    LL num[MAXN];
    
    LL gcd(LL a,LL b){return !b?a:gcd(b,a%b);}
    LL lcm(LL a,LL b){return a*b/gcd(a,b);}//求最小公倍数
    
    void dfs(LL x,LL p,LL t)
    {
        if(t>b) return;//如果你算出来的t比上界b还大,[a,b]中就肯定没有t的倍数了
        if(x%2==0) ans+=b/t-a/t;
        else ans-=b/t-a/t;//根据奇偶加减
        for(int i=p+1;i<=N;i++)//防止重复,从p+1开始
            dfs(x+1,i,lcm(t,num[i]));//注意一定是lcm(t,num[i]),我就因为写的t*num[i]而直接尴尬
    }
    
    int main()
    {
        cin>>N;//long long的格式控制符windows和linux系统评测不一样,索性就直接cin,cout了
        for(int i=1;i<=N;i++)
            cin>>num[i];
        cin>>a>>b;
        a--;//算的是[0,a),所以提前a--
        dfs(0,0,8);//8肯定是全部要算上的,所以t从8开始
        cout<<ans;
    }
    
  • 相关阅读:
    Delphi文件操作读文件写文件操作文件
    delphi7 开发ActiveX的学习备忘录
    delphi延时函数详细说明
    delphi如何保存和读取utf8的文本文件
    Delphi中线程的释放介绍[转]
    python IsWindowEnabled遍历windows的所有窗口并输出窗口标题
    如何把 XML 文件显示为 HTML 表格
    delphi把Frame嵌入一个Form
    Delphi如何实现内存共享
    about linux vps
  • 原文地址:https://www.cnblogs.com/LinqiongTaoist/p/7203723.html
Copyright © 2011-2022 走看看