HDU 5778 abs

题意转化一下就是寻找一个数P,要求P质因素分解完后,质因素没有重复,还要保证abs(P*P-x)最小。

暴力,在sqrt(x)附近向下向上分别枚举一下。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<ctime>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-8;
void File()
{
    freopen("D:\\in.txt","r",stdin);
    freopen("D:\\out.txt","w",stdout);
}
inline int read()
{
    char c = getchar();  while(!isdigit(c)) c = getchar();
    int x = 0;
    while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); }
    return x;
}

const int S=20;

LL mult_mod(LL a,LL b,LL c)
{
    a%=c; b%=c; LL ret=0;
    while(b)
    {
        if(b&1){ret+=a;ret%=c;} a<<=1;
        if(a>=c)a%=c; b>>=1;
    }
    return ret;
}

LL pow_mod(LL x,LL n,LL mod)
{
    if(n==1)return x%mod;
    x%=mod; LL tmp=x,ret=1;
    while(n)
    {
        if(n&1) ret=mult_mod(ret,tmp,mod);
        tmp=mult_mod(tmp,tmp,mod); n>>=1;
    }
    return ret;
}

bool check(LL a,LL n,LL x,LL t)
{
    LL ret=pow_mod(a,x,n);
    LL last=ret;
    for(int i=1;i<=t;i++)
    {
        ret=mult_mod(ret,ret,n);
        if(ret==1&&last!=1&&last!=n-1) return true;
        last=ret;
    }
    if(ret!=1) return true;
    return false;
}

bool Miller_Rabin(LL n)
{
    if(n<2)return false;
    if(n==2)return true;
    if((n&1)==0) return false;
    LL x=n-1,t=0;
    while((x&1)==0){x>>=1;t++;}
    for(int i=0;i<S;i++)
    {
        LL a=rand()%(n-1)+1;
        if(check(a,n,x,t)) return false;
    }
    return true;
}

LL factor[100];
int tol;

LL gcd(LL a,LL b)
{
    if(a==0)return 1;
    if(a<0) return gcd(-a,b);
    while(b) { LL t=a%b; a=b; b=t; }
    return a;
}

LL Pollard_rho(LL x,LL c)
{
    LL i=1,k=2,x0=rand()%x,y=x0;
    while(1)
    {
        i++;
        x0=(mult_mod(x0,x0,x)+c)%x;
        LL d=gcd(y-x0,x);
        if(d!=1&&d!=x) return d;
        if(y==x0) return x;
        if(i==k){y=x0;k+=k;}
    }
}

void findfac(LL n)
{
    if(Miller_Rabin(n)) { factor[tol++]=n; return; }
    LL p=n;
    while(p>=n)p=Pollard_rho(p,rand()%(n-1)+1);
    findfac(p); findfac(n/p);
}

int T;
LL x,ans;

int main()
{
    srand(time(NULL)); scanf("%d",&T);
    while(T--)
    {
        scanf("%lld",&x);
        if(x==1) {printf("3\n"); continue;}
        if(x==2) {printf("2\n"); continue;}
        if(x==3) {printf("1\n"); continue;}

        LL n=(LL)sqrt(1.0*x);
        ans=x;
        for(LL i=n;i>=1;i--)
        {
            tol=0; findfac(i); sort(factor,factor+tol);
            bool fail=0; for(int j=0;j<tol-1;j++) if(factor[j]==factor[j+1]) fail=1;
            if(fail==1) continue;
            else { ans=abs(x-i*i); break;}
        }

        for(LL i=n+1;;i++)
        {
            tol=0; findfac(i); sort(factor,factor+tol);
            bool fail=0; for(int j=0;j<tol-1;j++) if(factor[j]==factor[j+1]) fail=1;
            if(fail==1) continue;
            else { ans=min(ans,abs(x-i*i)); break;}
        }
        printf("%lld\n",ans);

    }
    return 0;
}

 

posted @ 2016-08-01 10:34  Fighting_Heart  阅读(136)  评论(0编辑  收藏  举报