HDU 5750 Dertouzos 简单数学

感悟:这又是zimpha巨出的一场题,然后04成功fst(也就是这题)

        实际上还是too young,要努力增加姿势,

分析:直接枚举这些数不好枚举,换一个角度,枚举x*d,也就是d的另一个乘数是多少

        显然  x<=min(d,(n-1)/d),x还得是质数,最后发现x必须小于d的最小因子

        然后预处理10w以内的素数,然后每次先得到k=min(d,(n-1)/d),然后看d最小因子是否小于k

        这题的关键就在找d的最小因子,我是暴力找的(然后碰上全是大素数就t了)

        实际上当d是大素数的时候,k很小,直接枚举质数,如果大于k还没有,就不用再找了(反正去最小)

        赛后加上这一个限制就过了

吐槽:还是年轻

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <vector>
#include <math.h>
#include <stack>
#include <map>
#define x first 
#define y second 
using namespace std;
typedef long long LL;
const int N = 1e5+5;
const int INF = 0x3f3f3f3f;
typedef pair<int,int>pii;
bool vis[N];
int prime[N>>1],tot;
void getprime(){
  for(int i=2;i*i<=N-5;++i){
    if(vis[i])continue;
    for(int j=i*i;j<=N-5;j+=i)
      vis[j]=true;
  }
  for(int i=2;i<=N-5;++i)
    if(!vis[i])prime[++tot]=i;
}
int main(){
   
  getprime();
  int T;
  scanf("%d",&T);
  while(T--){
   int n,d;
   scanf("%d%d",&n,&d);
   int tmp=min(d,(n-1)/d);
   int flag=-1;
   for(int i=1;i<=tot&&prime[i]<=tmp&&1ll*prime[i]*prime[i]<=d;++i){
      if(d%prime[i])continue;
      else {flag=prime[i];break;}
   }
   if(flag==-1)flag=d;
   tmp=min(tmp,flag);
   int k=lower_bound(prime+1,prime+1+tot,tmp)-prime;
   if(k==tot+1||prime[k]>tmp)--k;
   printf("%d
",k);
  }
  return 0;
}
View Code
原文地址:https://www.cnblogs.com/shuguangzw/p/5700308.html