[hoj 2576 2577]Simple Computing & II

基本思想都是用容斥原理。

hoj 2576 给出一组数x1...xn,问从1到m中能有多少个数能够整除这组数中的至少一个数。

hoj 2577 给出一组数x1...xn,问从1到m中能有多少个数能够整除这组数中的唯一的数。

2576

x1 + x2 + x3 - x1*x2 - x1*x3 - x2*x3 + x1*x2*x3;

即奇加偶减。

2677

x1 + x2 + x3 - 2*(x1*x2 - x1*x3 - x2*x3) + 3(x1*x2*x3);

即:仍然是奇加偶减,但是要乘以相应的等于乘数个数的系数。

/*使用容斥原理之后,就可以不关注具体的某个数可以被几整除,而是在总体上直接计数.*/

2576代码(自己敲一遍)

注意:虽然输入和最终的答案都是int,但是中间结果会爆int...

#include <cstdio>
using namespace std;
typedef long long ll;
const int MAXN = 11;
int x[MAXN];
ll Gcd(ll x,ll y)
{
    return (y==0)?x:Gcd(y,x%y);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m;
        scanf("%d %d",&n,&m);
        for(int i=0;i<n;i++)
            scanf("%d",x+i);
        ll sum = 0;
        int bits;
        ll s;
        for(int i=1;i<(1<<n);i++)
        {
            s = 1;
            bits = 0;
            for(int j=0;j<n;j++)
                if(i & (1<<j))
                {
                    bits++;
                    s *= (ll)x[j]/Gcd(s,x[j]);
                }
            ll tmp = m/s;
            if(bits&1)    sum += tmp;
            else    sum -= tmp;
        }
        printf("%d\n",(int)sum);
    }
}



2577代码(来源:http://www.2cto.com/kf/201304/204140.html有改动)

#include <cstdio>
using namespace std;
long long x[12];
long long gcd(long long a,long long b)
{
    while(b)
    {
        int c = a%b;
        a = b;
        b = c;
    }
    return a;
}
int main()
{
    int t;
    scanf(" %d",&t);
    while(t--)
    {
        long long n,m;
        long long sum = 0;
        scanf(" %lld %lld",&n,&m);

        for(long long i=0; i<n; i++)
        {
            scanf(" %lld",&x[i]);
        }
        for(long long i = 1; i<(1<<n); i++)//遍历所有方案
        {
            long long s = 1;//当前方案对应的除数
            long long bits = 0;//选择了几个数
            for(long long j=0; j<n; j++)
            {
                if(i &(1<<j))
                {
                    bits++;
                    s *= x[j]/gcd(s,x[j]);//求∪
                }
            }
            long long temp = m/s;//1..m内可被s整除的数的个数
            //bits是奇数时
            if(bits&1)
            {
                sum +=temp*bits;
            }
            else
            {
                sum -=temp*bits;
            }
        }
        printf("%lld\n",sum);
    }
}


你可能感兴趣的:([hoj 2576 2577]Simple Computing & II)