您的位置:首页 > 其它

[jzoj2538]【NOIP2009TG】Hankson 的趣味题

2017-11-02 18:24 302 查看

Description



0<NUM<2∗1010

Solution

比较简单的数论

基本思路:考虑 x 的每个质因数可以取多少个 运用乘法原理即可

显然的 P | x 的充要条件是 P | b1

那么 对于一个质数 P

设 A1 表示 Pf|a1 时最大的 f 以此类推

感受一下

当 A0=A1 时 x 中至多有 A1 个 P

A0>A1 时 x中恰好有 A1 个 P

A0<A1 时 无解

同样的 对于 B0和B1 我们一样的方式处理

注意每一个 b1 的质因数都要被考虑

Code

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define fo(i,x,y) for (int i=(x);i<=(y);++i)
#define fd(i,x,y) for (int i=(x);i>=(y);--i)
#define oo 2139062143
using namespace std;
const int NUM=2000020000,SQT=50500;
int T,a0,a1,b0,b1;
int pri[SQT],bz[SQT];
void gtpri()
{
bz[1]=1;
fo(i,2,50000)
{
if(!bz[i]) pri[++pri[0]]=i;
fo(j,1,pri[0])
{
if(i*pri[j]>=50000)break;
bz[i*pri[j]]=1;
if(!(i%pri[j]))break;
}
}
}
int calc(int x,int y)
{
int rt=0;
while(!(y%x)) y/=x,++rt;
return (rt);
}
int work(int P)
{
int c0=calc(P,a0),c1=calc(P,a1),d0=calc(P,b0),d1=calc(P,b1);
int tl=0,tr=oo;
if(c0<c1||d0>d1) return 0;
if(c0==c1) tl=c1;
if(d0==d1) tr=d1;
if(c0>c1)
{
if(!(c1>=tl&&c1<=tr)) return 0;
else tl=tr=c1;
}
if(d0<d1)
{
if(!(d1>=tl&&d1<=tr)) return 0;
else tl=tr=d1;
}
return(tr-tl+1);
}
int main()
{
gtpri();
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d%d",&a0,&a1,&b0,&b1);
long long ans=1;
fo(i,1,pri[0])
if(b1%pri[i]==0)
{
ans*=work(pri[i]);
while(b1%pri[i]==0) b1/=pri[i];
if(!ans||(pri[i]*pri[i]>=b1))break;
}
if(b1!=1)ans*=work(b1);
printf("%lld\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: