首页 > 代码库 > HDU5447 Good Numbers

HDU5447 Good Numbers

http://acm.hdu.edu.cn/showproblem.php?pid=5447

 

网上好像只找到java的题解,写完就发一下c++代码咯,顺便纪念一下+存个int128板子

做法可以看tjz直播中的pdf:http://www.51nod.com/live/liveDescription.html#!liveId=5

 

技术分享
#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define ll MMH
#define ull unsigned long long
using namespace std;

inline ull M(ull x,ull MOD){while (x>=MOD)x-=MOD;return x;}
inline ull cheng(ull a,ull b,ull p){
    ull mmh=0;
    while (b){
        if (b&1) mmh=M(mmh+a,p);
        a=M(a+a,p);b>>=1;
    }
    return mmh;
}
char P_C[50],O_O[50];
char c[50]={"24408308522758834075998738377"};
char ss[36][50]={"18446744073709551616","36893488147419103232","73786976294838206464","147573952589676412928","295147905179352825856","590295810358705651712","1180591620717411303424","2361183241434822606848","4722366482869645213696","9444732965739290427392","18889465931478580854784","37778931862957161709568","75557863725914323419136","151115727451828646838272","302231454903657293676544","604462909807314587353088","1208925819614629174706176","2417851639229258349412352","4835703278458516698824704","9671406556917033397649408","19342813113834066795298816","38685626227668133590597632","77371252455336267181195264","154742504910672534362390528","309485009821345068724781056","618970019642690137449562112","1237940039285380274899124224","2475880078570760549798248448","4951760157141521099596496896","9903520314283042199192993792","19807040628566084398385987584","39614081257132168796771975168","79228162514264337593543950336","158456325028528675187087900672","316912650057057350374175801344","633825300114114700748351602688"};
inline bool ju(int i){
    int cl=strlen(c),sl=strlen(ss[i]);
    if (cl<sl) return 0;else
    if (cl==sl) for (register int j=0;j<cl;j++) if (c[j]<ss[i][j]) return 0;else if (c[j]>ss[i][j]) break;
    for (register int j=0;j<cl-sl;j++) c[j]-=48;
    for (register int j=0;j<sl;j++) c[cl-j-1]-=ss[i][sl-j-1];
    for (register int j=0;j<cl;j++)
    for (register int j=cl-1;j;j--)
    if (c[j]<0) c[j]+=10,c[j-1]--;
    for (i=0;c[i]==0&&i<cl;i++);
    if (i==cl) c[0]=0,c[1]=0;else for (register int j=i;j<=cl;j++) c[j-i]=c[j]+48;c[cl-i]=0;
    return 1;
}
inline unsigned long long change(){
    int cl=strlen(c);
    unsigned long long x=0;
    for (register int i=0;i<cl;i++) x*=10,x+=c[i]-48;
    return x;
}
inline void add(int x){
    int i;
    int cl=strlen(P_C),sl=strlen(ss[x]);
    for (i=0;i<sl;i++) O_O[i]=ss[x][sl-i-1]-48;
    for (i=0;i<cl;i++) O_O[cl-i-1]+=P_C[i]-48;
    if (sl>cl) cl=sl;
    for (i=0;i<cl;i++)
    if (O_O[i]>=10) O_O[i+1]+=O_O[i]/10,O_O[i]%=10,cl+=i==(cl-1);
    for (i=0;i<cl;i++) P_C[i]=O_O[cl-i-1]+48;P_C[cl]=0;
}
struct MMH{
    unsigned long long a,b;
    MMH(ull _a=0,ull _b=0):a(_a),b(_b){}
    void half(){
        b>>=1;
        if (a&1) b|=1ull<<63;
        a>>=1;
    }
    void two(){
        a<<=1;
        if (b&(1ull<<63)) a|=1;
        b<<=1;
    }
    void pr(){
        ull A=a,B=b;int s=0;
        memset(P_C,0,sizeof(P_C));
        memset(O_O,0,sizeof(O_O));
        while(B) O_O[s++]=B%10+48,B/=10;P_C[s]=0;
        for (register int i=0;i<s;i++) P_C[i]=O_O[s-i-1];
        for (register int i=0;i<=35;i++)
        if (A&(1ull<<i)) add(i);
        printf("%s ",P_C);
    }
};
MMH operator +(const MMH &x,const MMH &y){
    MMH z;
    z.a=x.a+y.a;z.b=x.b+y.b;if (z.b<x.b||z.b<y.b) z.a++;
    return z;
}
MMH operator +(const MMH &x,const int &y){
    MMH z=x;
    if ((z.b+y)<z.b) z.a++;z.b+=y;
    return z;
}
MMH operator -(const MMH &x,const MMH &y){
    MMH z;
    z.a=x.a-y.a;z.b=x.b-y.b;if (y.b>x.b) z.a--;
    return z;
}
MMH operator -(const MMH &x,const int &y){
    MMH z=x;
    if (z.b<y) z.a--;z.b-=y;
    return z;
}
MMH operator *(const MMH &x,const MMH &y){
    if (x.a){
        MMH z=x,mmh=MMH(0,0),u=y;
        while (u.a|u.b){
            if (u.b&1) mmh=mmh+z;
            z.two();u.half();
        }
        return mmh;
    }
    ull s=(1ull<<32)-1;
    ull a=(x.b>>32)*(y.b>>32),_b1=(x.b&s)*(y.b>>32),b=_b1+(x.b>>32)*(y.b&s),c=(x.b&s)*(y.b&s),d;
    a+=(b<_b1)*1ull<<32;
    d=c+((b&s)<<32);a+=d<c;a+=b>>32;
    return MMH(a,d);
}
bool operator <(const MMH &x,const MMH &y){return x.a==y.a?x.b<y.b:x.a<y.a;}
bool operator >(const MMH &x,const MMH &y){return x.a==y.a?x.b>y.b:x.a>y.a;}
bool operator !=(const MMH &x,const MMH &y){return x.a!=y.a||x.b!=y.b;}
bool operator ==(const MMH &x,const MMH &y){return x.a==y.a&&x.b==y.b;}
MMH operator %(const MMH &x,const MMH &y){
    if (x<y) return x;
    MMH z=y,c=x;
    while (!(z>c)) z.two();
    for(;;){
        z.half();
        if (!(c<z))c=c-z;
        if (z.a==y.a&&z.b==y.b) break;
    }
    return c;
}
MMH operator /(const MMH &x,const MMH &y){
    if (x<y) return MMH{0,0};
    MMH z=y,c=x,a=MMH{0,0};
    while (!(z>x)) z.two();
    for(;;){
        z.half();a.two();
        if (!(c<z))c=c-z,a.b|=1;
        if (z.a==y.a&&z.b==y.b) break;
    }
    return a;
}
int operator %(const MMH &x,const int &y){
    MMH z=x;
    z.a%=y;z.b%=y;
    z.a<<=32;z.a%=y;
    z.a<<=32;z.a%=y;
    
    z.b+=z.a;if (z.b>=y) z.b-=y;
    return z.b;
}
ull sqrt(MMH x){
    ull l=0,r=1e18,_mid;
    MMH mid;
    while (l<r){
        mid.a=0;mid.b=_mid=l+r>>1;
        mid=mid*mid;
        if (x==mid) return _mid;else if (x<mid) r=_mid-1;else if (x>mid) l=_mid+1;
    }
    return l;
}
ull sqrt3(MMH x){
    ull l=0,r=1e12,_mid;
    MMH mid=MMH(0,0);
    while (l<r){
        mid.a=0;mid.b=_mid=l+r>>1;
        mid=mid*mid*mid;
        if (x==mid) return _mid;else if (x<mid) r=_mid-1;else if (x>mid) l=_mid+1;
    }
    return l;
}
ull operator %(const MMH &x,const ull &y){
    MMH z=x;
    z.a%=y;z.b%=y;
    for (int i=0;i<64;i++) z.a<<=1,z.a%=y;
    
    z.b+=z.a;if (z.b>=y) z.b-=y;
    return z.b;
}
inline void read(MMH &n){
    scanf("%s",c);
    n.a=n.b=0;
    for (int i=35;i>=0;i--){
        n.a<<=1;
        if (ju(i)) n.a|=1;
    }
    n.b=change();
}
const int S=20;
const ull m_p[20]={2,5,7,61,97,37,101,13,11,997,2083,5807,7213,9907,10781,11897,14033,18013,43789,10009};
ll cheng(ll a,ll b,ll p){
    ll mmh;mmh=MMH{0,0};
    while (b.a||b.b){
        if (b.b&1) if (mmh=mmh+a,!(mmh<p)) mmh=mmh-p;
        b.half();a=a+a;if (!(a<p)) a=a-p;
    }
    return mmh;
}
ll mi(ll a,ll b,ll p){
    ll mmh;mmh={0,1};
    while (b.a||b.b){
        if (b.b&1ull) mmh=cheng(mmh,a,p);
        b.half();a=cheng(a,a,p);
    }
    return mmh;
}
bool prime_judge(ll n){
    if(n.b==2&&n.a==0) return 1;
    if((n.b<2&&n.a==0)||!(n.b&1)) return 0;
    for (register int i=0;i<S;i++)
    if (m_p[i]==n.b&&n.a==0) return 1;else if (mi(MMH{0,(n.a?m_p[i]:m_p[i]%n.b)},n-1,n)!=MMH{0,1}) return 0;
    return 1;
}
ll gcd(ll x,ll y){return (y.a==0&&y.b==0)?x:gcd(y,x%y);}
ll k1,k2,u;
#define MN 1000001
bool bo[MN];
ull mmh1,mmh2,T,p[MN],num=0,A;
inline void work(ll k,ull &mmh,ll u){
    if (u.a) return;
    ull s=u.b;
    if (s<1e8&&k==u*u*u) mmh*=3;else
    if (k==u*u||(s<=1e8&&k%(s*s)==0)) mmh*=2;else{
        if (k==u) return;
        k=k/u;
        u=MMH(0,sqrt(k));
        if (u*u==k) mmh<<=1;
    }
}
int main(){
    register int i,j;
    for (i=2;i<MN;i++){
        if (!bo[i]) p[++num]=i;
        for (j=1;j<=num&&i*p[j]<MN;j++)
        if (bo[i*p[j]]=1,i%p[j]==0) break;
    }
    scanf("%d",&T);
    while (T--){
        read(k1);read(k2);mmh1=mmh2=1;
        for (i=1;i<=num;i++)
        if (k1%p[i]==0){
            A=1;k1=k1/MMH{0,p[i]};
            while (k1%p[i]==0) A++,k1=k1/MMH{0,p[i]};
            mmh1=mmh1*A;
        }
        for (i=1;i<=num;i++)
        if (k2%p[i]==0){
            A=1;k2=k2/MMH{0,p[i]};
            while (k2%p[i]==0) A++,k2=k2/MMH{0,p[i]};
            mmh2=mmh2*A;
        }
        
        u=gcd(k1,k2);
        if (prime_judge(u)) work(k1,mmh1,u),work(k2,mmh2,u);else
        if (u!=MMH(0,1)){
            if (A=sqrt(u),u==MMH(0,A)*MMH(0,A)) mmh1*=(MMH(0,A)*u==k1)+2,mmh2*=(MMH(0,A)*u==k2)+2;else
            if (A=sqrt3(u),u==MMH(0,A)*MMH(0,A)*MMH(0,A)) mmh1*=3,mmh2*=3;
        }
        printf("%llu %llu\n",mmh1,mmh2);
    }
}
View Code

 

HDU5447 Good Numbers