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=;
while (b){
if (b&) mmh=M(mmh+a,p);
a=M(a+a,p);b>>=;
}
return mmh;
}
char P_C[],O_O[];
char c[]={""};
char ss[][]={"","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""};
inline bool ju(int i){
int cl=strlen(c),sl=strlen(ss[i]);
if (cl<sl) return ;else
if (cl==sl) for (register int j=;j<cl;j++) if (c[j]<ss[i][j]) return ;else if (c[j]>ss[i][j]) break;
for (register int j=;j<cl-sl;j++) c[j]-=;
for (register int j=;j<sl;j++) c[cl-j-]-=ss[i][sl-j-];
for (register int j=;j<cl;j++)
for (register int j=cl-;j;j--)
if (c[j]<) c[j]+=,c[j-]--;
for (i=;c[i]==&&i<cl;i++);
if (i==cl) c[]='',c[]=;else for (register int j=i;j<=cl;j++) c[j-i]=c[j]+;c[cl-i]=;
return ;
}
inline unsigned long long change(){
int cl=strlen(c);
unsigned long long x=;
for (register int i=;i<cl;i++) x*=,x+=c[i]-;
return x;
}
inline void add(int x){
int i;
int cl=strlen(P_C),sl=strlen(ss[x]);
for (i=;i<sl;i++) O_O[i]=ss[x][sl-i-]-;
for (i=;i<cl;i++) O_O[cl-i-]+=P_C[i]-;
if (sl>cl) cl=sl;
for (i=;i<cl;i++)
if (O_O[i]>=) O_O[i+]+=O_O[i]/,O_O[i]%=,cl+=i==(cl-);
for (i=;i<cl;i++) P_C[i]=O_O[cl-i-]+;P_C[cl]=;
}
struct MMH{
unsigned long long a,b;
MMH(ull _a=,ull _b=):a(_a),b(_b){}
void half(){
b>>=;
if (a&) b|=1ull<<;
a>>=;
}
void two(){
a<<=;
if (b&(1ull<<)) a|=;
b<<=;
}
void pr(){
ull A=a,B=b;int s=;
memset(P_C,,sizeof(P_C));
memset(O_O,,sizeof(O_O));
while(B) O_O[s++]=B%+,B/=;P_C[s]=;
for (register int i=;i<s;i++) P_C[i]=O_O[s-i-];
for (register int i=;i<=;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(,),u=y;
while (u.a|u.b){
if (u.b&) mmh=mmh+z;
z.two();u.half();
}
return mmh;
}
ull s=(1ull<<)-;
ull a=(x.b>>)*(y.b>>),_b1=(x.b&s)*(y.b>>),b=_b1+(x.b>>)*(y.b&s),c=(x.b&s)*(y.b&s),d;
a+=(b<_b1)*1ull<<;
d=c+((b&s)<<);a+=d<c;a+=b>>;
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{,};
MMH z=y,c=x,a=MMH{,};
while (!(z>x)) z.two();
for(;;){
z.half();a.two();
if (!(c<z))c=c-z,a.b|=;
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<<=;z.a%=y;
z.a<<=;z.a%=y; z.b+=z.a;if (z.b>=y) z.b-=y;
return z.b;
}
ull sqrt(MMH x){
ull l=,r=1e18,_mid;
MMH mid;
while (l<r){
mid.a=;mid.b=_mid=l+r>>;
mid=mid*mid;
if (x==mid) return _mid;else if (x<mid) r=_mid-;else if (x>mid) l=_mid+;
}
return l;
}
ull sqrt3(MMH x){
ull l=,r=1e12,_mid;
MMH mid=MMH(,);
while (l<r){
mid.a=;mid.b=_mid=l+r>>;
mid=mid*mid*mid;
if (x==mid) return _mid;else if (x<mid) r=_mid-;else if (x>mid) l=_mid+;
}
return l;
}
ull operator %(const MMH &x,const ull &y){
MMH z=x;
z.a%=y;z.b%=y;
for (int i=;i<;i++) z.a<<=,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=;
for (int i=;i>=;i--){
n.a<<=;
if (ju(i)) n.a|=;
}
n.b=change();
}
const int S=;
const ull m_p[]={,,,,,,,,,,,,,,,,,,,};
ll cheng(ll a,ll b,ll p){
ll mmh;mmh=MMH{,};
while (b.a||b.b){
if (b.b&) 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={,};
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==&&n.a==) return ;
if((n.b<&&n.a==)||!(n.b&)) return ;
for (register int i=;i<S;i++)
if (m_p[i]==n.b&&n.a==) return ;else if (mi(MMH{,(n.a?m_p[i]:m_p[i]%n.b)},n-,n)!=MMH{,}) return ;
return ;
}
ll gcd(ll x,ll y){return (y.a==&&y.b==)?x:gcd(y,x%y);}
ll k1,k2,u;
#define MN 1000001
bool bo[MN];
ull mmh1,mmh2,T,p[MN],num=,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*=;else
if (k==u*u||(s<=1e8&&k%(s*s)==)) mmh*=;else{
if (k==u) return;
k=k/u;
u=MMH(,sqrt(k));
if (u*u==k) mmh<<=;
}
}
int main(){
register int i,j;
for (i=;i<MN;i++){
if (!bo[i]) p[++num]=i;
for (j=;j<=num&&i*p[j]<MN;j++)
if (bo[i*p[j]]=,i%p[j]==) break;
}
scanf("%d",&T);
while (T--){
read(k1);read(k2);mmh1=mmh2=;
for (i=;i<=num;i++)
if (k1%p[i]==){
A=;k1=k1/MMH{,p[i]};
while (k1%p[i]==) A++,k1=k1/MMH{,p[i]};
mmh1=mmh1*A;
}
for (i=;i<=num;i++)
if (k2%p[i]==){
A=;k2=k2/MMH{,p[i]};
while (k2%p[i]==) A++,k2=k2/MMH{,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(,)){
if (A=sqrt(u),u==MMH(,A)*MMH(,A)) mmh1*=(MMH(,A)*u==k1)+,mmh2*=(MMH(,A)*u==k2)+;else
if (A=sqrt3(u),u==MMH(,A)*MMH(,A)*MMH(,A)) mmh1*=,mmh2*=;
}
printf("%llu %llu\n",mmh1,mmh2);
}
}

HDU5447 Good Numbers的更多相关文章

  1. Good Numbers(HDU5447+唯一分解)

    题目链接 传送门 题面 题意 首先定义对于\(k\)的好数\(u\):如果\(u\leq k\)且\(u\)的所有质因子与\(k\)的质因子一样则称\(u\)对于\(k\)是一个好数. 现给你两个数\ ...

  2. Java 位运算2-LeetCode 201 Bitwise AND of Numbers Range

    在Java位运算总结-leetcode题目博文中总结了Java提供的按位运算操作符,今天又碰到LeetCode中一道按位操作的题目 Given a range [m, n] where 0 <= ...

  3. POJ 2739. Sum of Consecutive Prime Numbers

    Sum of Consecutive Prime Numbers Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20050 ...

  4. [LeetCode] Add Two Numbers II 两个数字相加之二

    You are given two linked lists representing two non-negative numbers. The most significant digit com ...

  5. [LeetCode] Maximum XOR of Two Numbers in an Array 数组中异或值最大的两个数字

    Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Find the maximum re ...

  6. [LeetCode] Count Numbers with Unique Digits 计算各位不相同的数字个数

    Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. Examp ...

  7. [LeetCode] Bitwise AND of Numbers Range 数字范围位相与

    Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers ...

  8. [LeetCode] Valid Phone Numbers 验证电话号码

    Given a text file file.txt that contains list of phone numbers (one per line), write a one liner bas ...

  9. [LeetCode] Consecutive Numbers 连续的数字

    Write a SQL query to find all numbers that appear at least three times consecutively. +----+-----+ | ...

随机推荐

  1. AMD与CMD区别

    区别: 1. 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行.不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同).CMD 推崇 as lazy as ...

  2. Spring拦截器总结

    本文是对慕课网上"搞定SSM开发"路径的系列课程的总结,详细的项目文档和课程总结放在github上了.点击查看 Spring过滤器WebFilter可以配置中文过滤 拦截器实现步骤 ...

  3. 贪心算法——Fence Repair(POJ 3253)

    题目描述 农夫约翰为了修理栅栏,要将一块很长的木板切割成N块.准备切成的木板长度为L1,L2,L3--LN,未切割前木板的长度恰好为切割后木板长度的总和.每次切断木板时,需要的开销为这块木板的长度.请 ...

  4. mentohust 使用

    可使用帮助命令 mentohust -h 或着查看 https://wenku.baidu.com/view/95c08019ff00bed5b9f31d1a.html

  5. ubuntu下加载mcypt

    mcrypt 是php 里面重要的加密支持扩展库,linux环境下:该库在默认情况下不开启.window环境下:PHP>=5.3,默认开启mcrypt扩展 1.命令行下载(不嫌麻烦可以到网上找安 ...

  6. Prism for WPF再探(基于Prism事件的模块间通信)

    上篇博文链接 Prism for WPF初探(构建简单的模块化开发框架) 一.简单介绍: 在上一篇博文中初步搭建了Prism框架的各个模块,但那只是搭建了一个空壳,里面的内容基本是空的,在这一篇我将实 ...

  7. linux下后台运行MATLAB

    原帖:http://sypeterli1.blog.163.com/blog/static/2283740492013101745824207/ 后台运行matlab脚本文件的方法:nohup     ...

  8. linux shadowsocket 安装和启动

    http://blog.csdn.net/hanshileiai/article/details/49302865

  9. 一起学Linux02之Linux系统启动过程

    这个Linux系统启动过程啊,说实话,我认为,刚学习的时候看几遍,了解一下就好.现在的主要任务是用.熟练了之后再来深究这个不急. 下面我就简单地说说吧. Linux系统的启动主要分为下列步骤: 1 内 ...

  10. Java并发之底层实现原理学习笔记

    本篇博文将介绍java并发底层的实现原理,我们知道java实现的并发操作最后肯定是由我们的CPU完成的,中间经历了将java源码编译成.class文件,然后进行加载,然后虚拟机执行引擎进行执行,解释为 ...