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;
}

 

posted @ 2012-05-16 14:48  朝圣の路  阅读(344)  评论(0编辑  收藏  举报