我的第一道容斥原理...想法很直接,利用容斥原理求出[l,r]范围内与n互质的数的个数,然后枚举n,想法直接的代价就是时间消耗大,我用了1000ms..
比较好的容斥原理学习资料http://www.cnblogs.com/acSzz/archive/2012/11/18/2775923.html
代码:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
long long work(int n,int l,int r)//利用容斥原理,求l,r区间内与n互素的数的个数
{
vector<int> p;
int i,msk,bits,mult,cur,bound,t=r-l+1;
long long sum=0;
for(i=2;i*i<=n;++i)
{
if(n%i==0)
p.push_back(i);
while(n%i==0)
n/=i;
}
if(n>1)
p.push_back(n);
bound=1<<p.size();
for(msk=1;msk<bound;++msk)
{
mult=1;
bits=0;
for(i=0;i<p.size();++i)
{
if(msk&(1<<i))
{
bits++;
mult*=p[i];
}
}
cur=r/mult-(l-1)/mult;
if(bits&1)
sum+=cur;
else
sum-=cur;
}
return t-sum;
}
int main()
{
int a,b,c,d,k,T,i,j,cas=0;
long long ans;
scanf("%d",&T);
while(T--)
{
scanf("%d %d %d %d %d",&a,&b,&c,&d,&k);
cas++;
ans=0;
if(k!=0)
{
b/=k,d/=k;
if(b>d)
swap(b,d);
for(i=1;i<=b;++i)
ans+=work(i,i,d);
}
printf("Case %d: %I64d\n",cas,ans);
}
return 0;
}