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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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); } }