这道题的意思很清晰略掉。假设a1<b1,a1,b1同除k,那么在x<=a1时,求x的欧拉函数值。当x>a1时,求1-a1内与x1互质的数。本题细节非常多,首先是k=0的情况,然后又一个细节我一直没有考虑到,直到看了别人的代码才明白。。就是a1,b1同除玩k之后,看看这两个数有没有0。。。。附代码:
#include <iostream>
#include <vector>
using namespace std;
#define clear1(a) memset(a,0,sizeof(a))
const int N=100100;
int a[N],b[N],e[N],z;
vector<int>c;
int euler(int n)
{
int i,j;
if (!a[n])
{
e[n]=n-1;
if (n==1) e[n]=1;
return e[n];
}
for (i=1;i<=z;i++)
if (b[i]*b[i]<=n)
{
j=b[i];
if (n%j==0)
{
int n1=n/j;
if (n1%j==0) e[n]=j*e[n1];
else e[n]=e[n1]*(j-1);
break;
}
}
return e[n];
}
int running(int n,int i,int k,int now)
{
int j,res=0,r1;
if (i>c.size()) return 0;
for (j=k+1;j<c.size();j++)
{
r1=n/(now*c[j]);
if (r1==0) continue;
if (i%2==0) r1*=-1;
res+=r1+running(n,i+1,j,now*c[j]);
}
return res;
}
int deal(int n,int m)
{
int i,z1=0,n1=n;
for (i=1;i<=z;i++)
if (b[i]<=n1&&b[i]<=m)
{
if (n1%b[i]==0)
{
c.push_back(b[i]);
while (n1%b[i]==0&&n1>1) n1/=b[i];
if (n1==1) break;
}
}
else break;
if (c.empty()) return m;
else return m-running(m,1,-1,1);
}
int main()
{
int i,a1,b1,j,T,k;
scanf("%d",&T);
clear1(a);
clear1(b);
clear1(e);
z=0;
for (i=2;i<N;i++)
if (!a[i])
{
for (j=i*2;j<N;j+=i) a[j]=1;
b[++z]=i;
}
for (j=1;j<=T;j++)
{
int a0,b0;
scanf("%d%d",&a0,&a1);
scanf("%d%d",&b0,&b1);
scanf("%d",&k);
printf("Case %d: ",j);
if (k==0)
{
printf("%d\n",0);
continue;
}
a1/=k;
b1/=k;
if (a1>b1)
{
int tmp=a1;
a1=b1;
b1=tmp;
}
if (a1==0)
{
printf("%d\n",0);
continue;
}
__int64 zs=0;
for (i=1;i<=b1;i++)
{
if (i<=a1+1)
zs+=euler(i);
else
{
c.clear();
zs+=deal(i,a1);
}
}
printf("%I64d\n",zs);
}
return 0;
}