网上学到到的递归写法
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int fac[20];
void Init(int m)
{
int i,n=0;
for(i=2;i*i<=m;i++)
if(m%i==0){
fac[++n]=i;
while(m%i==0) m/=i;
}
if(m!=1) fac[++n]=m;
fac[0]=n;
}
__int64 Noprime(int m,__int64 n,int x)
{
__int64 i,ret=0;
for(i=x;i<=fac[0];i++)
ret+=n/fac[i]-Noprime(m,n/fac[i],i+1);
return ret;
}
int main()
{
int t,T,N;
__int64 A,B;
scanf("%d",&T);
for(t=1;t<=T;t++)
{
scanf("%I64d%I64d%d",&A,&B,&N); Init(N);
printf("Case #%d: %I64d\n",t,B-Noprime(N,B,1)-(A-1-Noprime(N,A-1,1)));
}
return 0;
}
袁神教的非递归写法,附笔记。。。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int fac[20];
void Get_fac(int m)
{
int i,n=0;
for(i=2;i*i<=m;i++)
if(m%i==0){
fac[++n]=i;
while(m%i==0) m/=i;
}
if(m!=1) fac[++n]=m;
fac[0]=n;
}
int sum[1<<11],q;
__int64 Sum(int m,__int64 n)
{
int i,j;
Get_fac(m);
sum[0]=1;
sum[1]=1;
for(i=1;i<=fac[0];i++)
{
int k=sum[0];
for(j=1;j<=sum[0];j++)
{
sum[++k]=fac[i]*sum[j]*-1;
}
sum[0]=k;
}
// for(i=1;i<=sum[0];i++) printf("%d ",sum[i]);printf("\n");
__int64 ret=n;
for(i=2;i<=sum[0];i++) ret+=n/sum[i];
return ret;
}
int main()
{
int t,T,N;
__int64 A,B;
scanf("%d",&T);
for(t=1;t<=T;t++)
{
scanf("%I64d%I64d%d",&A,&B,&N);
printf("Case #%d: %I64d\n",t,Sum(N,B)-Sum(N,A-1));
}
return 0;
}