您的位置:首页 > 其它

【HDOJ】【BestCoder Round #84】1004 Dertouzos

2016-07-25 19:51 281 查看
问题描述

正整数x 称为n 的positive proper divisor , 当且仅当x|n 并且1≤x<n . 例如, 1,2, 和3 是6 的positive proper divisor , 但是6 不是.

Peter 给你两个正整数n 和d . 他想要知道有多少小于n 的整数, 满足他们的最大positive proper divisor 恰好是d .

输入描述

输入包含多组数据, 第一行包含一个整数T(1≤T≤10 6 ) 表示测试数据组数. 对于每组数据:

第一行包含两个整数n 和d (2≤n,d≤10 9 ) .

输出描述

对于每组数据, 输出一个整数.

Solution

我们反过来考虑,给定一个d ,它可以作为谁的ppd (原谅我懒)

以下为最终结论……

根据题目中给出的定义,我们可以知道,如果一个数a∗d ,它的ppd 是d ,那么需要满足的条件就是a≤b ,b 是d 的非1 最小因数,a 为质数。

(如果a 不为质数,它就可以拆出个最小非1 因数e ,则a∗d=e∗(ae ∗d) ,也就是说,它的ppd 就是(ae ∗d) ,而不是d )

(类似的,我们可以知道如果a>b ,也可以导出d 不是ppd 的结论)

那么问题就是统计有多少质数a ,满足

1、 a≤b (b 为d 最小非1 约数)

2、 a∗d<n

对于d 较小时,采用第一种方式约束枚举次数,反之使用第二种方式

(然而Claris 大大放的加强数据中有4e5 个超大质数,第一版数据具体怎样也不知道,我只用了第二种方式约束就跑过了)

(自己简单估计,应该是1e5 上下的质数一多,我的程序就T 飞了)

#include<stdio.h>
#define lim 100007

bool b[lim+1];
int p[lim],n,d,T,tot;

int main()
{
for (int i=2;i<=lim;i++) if (!b[i]) for (int j=i<<1;j<=lim;j+=i) b[j]=1;
for (int i=2;i<=lim;i++) if (!b[i]) p[tot++]=i;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&d);
int i;
for (i=0;i<tot && d*p[i]<n;i++) if (d % p[i]==0)
{
i++;
break;
}
printf("%d\n",i);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: