2 1 3 1 5 1 1 11014 1 14409 9
Case 1: 9 Case 2: 736427HintFor the first sample input, all the 9 pairs of numbers are (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 5), (3, 4), (3, 5).
一道比较经典的题目,可以用容斥原理,也可以莫比乌斯反演,莫比乌斯反演暂时没实现,就是把b,d都除以k,然后查找互素对数,枚举+容斥,一个特判的trick纠结了一天,
被dream神三分钟就找到了,
代码:
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
typedef __int64 ll;
bool isprime[1001000];
ll prime[1001000],factor[1010];
void getprime(){
memset(isprime,1,sizeof(isprime));isprime[1]=0;
ll &cnt=prime[0];cnt=0;
for(ll i=2;i<=1000000;i++){
if(isprime[i])prime[++cnt]=i;
for(ll j=1;j<=cnt&&i*prime[j]<=1000000;j++){
isprime[i*prime[j]]=0;
if(i%prime[j]==0)break;
}
}
// cout<<prime[0]<<endl;
}
void getfactor(ll x){
ll &cnt=factor[1000];cnt=0;
for(ll i=1;i<=prime[0]&&prime[i]*prime[i]<=x;i++)
if(x%prime[i]==0){
factor[cnt++]=prime[i];
while(x%prime[i]==0)x/=prime[i];
}
if(x>1)factor[cnt++]=x;
}
ll cal(ll x){
ll cnt=factor[1000],ans=0;
for(ll i=1;i<(1<<cnt);i++){
ll pp=1,ss=0;
for(ll j=0;j<cnt;j++)
if(i&(1<<j)){
ss++;pp*=factor[j];
}
if(ss%2)ans+=x/pp;
else ans-=x/pp;
}
return x-ans;
}
int main()
{
//freopen("data.in","r",stdin);
// freopen("data.out","w",stdout);
getprime();
int T;scanf("%d",&T);
for(int t=1;t<=T;t++){
ll a,b,c,d,k;
scanf("%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&d,&k);
printf("Case %d: ",t);
if(k==0){
puts("0");continue;
}
ll ans=0;
if(b>d)swap(b,d);b/=k;d/=k;
if(b)ans+=d;
for(ll i=2;i<=b;i++){
getfactor(i);
ans+=cal(d)-cal(i);
}
cout<<ans<<endl;
}
return 0;
}
hdu 1695 容斥原理或莫比乌斯反演,布布扣,bubuko.com
原文:http://blog.csdn.net/xianxingwuguan1/article/details/22901813