新视野OJ 2301 [HAOI2011]Problem b (数论-gcd)

来源:互联网 发布:园林设计软件图库 编辑:程序博客网 时间:2024/05/16 16:13

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2301


题意:对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k。

题解:和前几道题差不多,就是xy不是从1开始了,所以我们很容易联想到容斥原理,ans=gcd(b,d)-gcd(a-1,d)-gcd(b,c-1)+gcd(a-1,b-1)。


AC代码:

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cstdlib>#include <cmath>#include <vector>#include <list>#include <deque>#include <queue>#include <iterator>#include <stack>#include <map>#include <set>#include <algorithm>#include <cctype>using namespace std;#define si1(a) scanf("%d",&a)#define si2(a,b) scanf("%d%d",&a,&b)#define sd1(a) scanf("%lf",&a)#define sd2(a,b) scanf("%lf%lf",&a,&b)#define ss1(s)  scanf("%s",s)#define pi1(a)    printf("%d\n",a)#define pi2(a,b)  printf("%d %d\n",a,b)#define mset(a,b)   memset(a,b,sizeof(a))#define forb(i,a,b)   for(int i=a;i<b;i++)#define ford(i,a,b)   for(int i=a;i<=b;i++)typedef long long LL;const int N=500005;const int INF=0x3f3f3f3f;const double PI=acos(-1.0);const double eps=1e-7;LL f[N];LL k;LL xiaohao(LL n,LL m){    if(n<k||m<k)    return 0;    if(n>m) swap(n,m);    n/=k;   m/=k;    LL sum=0;    for(LL i=n;i>=1;i--)    {        f[i]=(n/i)*(m/i);        for(LL j=i+i;j<=n;j+=i)            f[i]-=f[j];    }    return f[1];}int main(){//    freopen("input.txt","r",stdin);    LL a,b,c,d;    int T;    scanf("%d",&T);    while(T--)    {        //scanf("%lld%lld%lld%lld%lld",&a,&b,&c,&d,&k);        cin>>a>>b>>c>>d>>k;        if(a>b||c>d)        {            puts("0");            continue;        }        cout<<xiaohao(b,d)-xiaohao(a-1,d)-xiaohao(c,b-1)+xiaohao(a-1,b-1)<<endl;    }    return 0;}


#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cstdlib>#include <cmath>#include <vector>#include <list>#include <deque>#include <queue>#include <iterator>#include <stack>#include <map>#include <set>#include <algorithm>#include <cctype>using namespace std;#define si1(a) scanf("%d",&a)#define si2(a,b) scanf("%d%d",&a,&b)#define sd1(a) scanf("%lf",&a)#define sd2(a,b) scanf("%lf%lf",&a,&b)#define ss1(s)  scanf("%s",s)#define pi1(a)    printf("%d\n",a)#define pi2(a,b)  printf("%d %d\n",a,b)#define mset(a,b)   memset(a,b,sizeof(a))#define forb(i,a,b)   for(int i=a;i<b;i++)#define ford(i,a,b)   for(int i=a;i<=b;i++)typedef long long LL;const int N=50000;const int INF=0x3f3f3f3f;const double PI=acos(-1.0);const double eps=1e-7;LL x;LL A,B,C,D,K;LL mu[N+10],sum[N+10],prime[N+10];bool com[N+1];void GetPrimes(){    memset(com,0,sizeof(com));    mu[1]=1;    x=0;    for(LL i=2;i<=N;++i)    {        if (!com[i])    { prime[x++] = i; mu[i] = -1; }        for (LL j=0;j<x&&i*prime[j]<=N;++j)        {            com[i*prime[j]] = true;            if (i%prime[j]) mu[i*prime[j]] = -mu[i];            else { mu[i*prime[j]] = 0; break; }        }    }    for (LL i=1;i<=N;++i)        sum[i] = sum[i-1] + mu[i];}LL Process(LL n,LL m){    LL res=0;    if(n>m) swap(n,m);    for(LL i=1,last=0;i<=n;i=last+1)    {        last=min(n/(n/i),m/(m/i));        res+=(sum[last]-sum[i-1])*(n/i)*(m/i);    }    return res;}int main(){//    freopen("input.txt","r",stdin);    GetPrimes();    int T;    scanf("%d",&T);    while(T--)    {        scanf("%lld%lld%lld%lld%lld",&A,&B,&C,&D,&K);        LL ans=0;        ans+=Process(B/K,D/K);        ans-=Process((A-1)/K,D/K);        ans-=Process(B/K,(C-1)/K);        ans+=Process((A-1)/K,(C-1)/K);        printf("%lld\n",ans);    }}


原创粉丝点击