hdu 1159

唉。。。这两天真是多灾多难啊。。。净碰到蛋疼的题。犯一些蛋疼的错误(这题是在一个判断的地方关系弄错了)。

这题的主要原理是多个集合的容斥原理。

代码如下:

#include"stdio.h"

#include"math.h"



__int64 prime[10005]={2,3},count=2;

__int64 cnt,factor[20];

__int64 n,m,ans;



void cal()

{

    int i,j,flag;

    for(i=5;i<100000;i+=2)

    {

        flag=0;

        for(j=0;j<count;j++)

            if(i%prime[j]==0)

            {flag=1;break;}

        if(flag==0)

            prime[count++]=i;

    }

}



void cal1(int n)

{

    int i,lim=(int)sqrt(n)+1;

    cnt=0;

    for(i=0;prime[i]<=lim&&n!=1;i++)

    {

        if(n%prime[i]==0)

            factor[cnt++]=prime[i];

        while(n%prime[i]==0)

            n/=prime[i];

    }

    if(n!=1)

        factor[cnt++]=n;

}



void rescure(int x,int sign,int num,int dcn,int d)

{

    int i;

    if(sign==1)

    {

        num*=factor[d];

        dcn++;

    }

    if(d+1==cnt)

    {

        if(num==1)

            return ;

        if(dcn%2==1)

            ans+=(n-x)/num;

        else

            ans-=(n-x)/num;

        return ;

    }

    for(i=0;i<=1;i++)

        rescure(x,i,num,dcn,d+1);

}



int main( )

{

    __int64 a,b,c,d,k,i,j,t,ncase=0;

    __int64 sum;

    cal();

    scanf("%I64d",&t);

    while(t--)

    {

        ncase++;

        scanf("%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&d,&k);

        printf("Case %d: ",ncase);

        if(k>b||k>d||k==0)

        {

            printf("0\n");

            continue;

        }

        m=b<d?b/k:d/k;

        n=b>d?b/k:d/k;

        sum=n*m-m*(m+1)/2+1;

        ans=0;

        for(i=2;i<=m;i++)

        {

            cal1(i);

            for(j=0;j<=1;j++)

                rescure(i,j,1,0,0);

        }

        printf("%I64d\n",sum-ans);

    }

    return 0;

}

 

你可能感兴趣的:(HDU)