Time Limits: 2000 ms Memory Limits: 131072 KB Detailed Limits
Description
在一门叫做计算机应用数学的神奇的课上,老师教给大家如何处理小数的进制转换:
p进制的小数abc.def的十进制值为: a*p^2+b*p+c+d/p+e/p^2 +f/p^3 。
例如十进制数 1/3 在十进制下小数表示为0.33333…,在三进制下为0.1,在三十进制下为0.A。(这里A的含义与十六进制中A的含义相同,均表示10)。
下课后,老师要求kAc将N个十进制的分数写成k进制下的小数。然而kAc发现,很多十进制分数根本不可能写成有限的k进制小数!这令他十分不爽,不过他想知道,最小需要几进制才能使得这些十进制分数在该进制下均为有限的小数。
Input
第一行一个整数N
接下来N行,每行两个整数a, b,表示一个十进制小数a/b 。
Output
一个整数,表示最小进制数。这里,请按照十六进制输出,所有字母全部大写。(例如,如果答案为十进制下26,则输出1A)。
Sample Input
3 3 99 1 99 1 11
Sample Output
21
Data Constraint
对于20%的测试数据:n=1
对于50%的测试数据:n<=10,a, b <= 10000,保证最终答案在十进制下不超过10000。
对于70%的测试数据:n<=100,a, b<= 10000。
对于100%的测试数据:n<=1000,1 <= a,b <= 1000000000。
Hint
样例解释:
在33进制下,3/99可以表示为0.1,1/99可以表示为0.0B,1/11可以表示为0.3。
可以证明不存在更小的进制,使得他们均为有限小数。
考场:
比赛时本以为能切。
考虑一个fraction a / b 在 k进制下是有限的那么 必定存在 一整数P, 使 bp = k^x次方。
所以p = k ^ x / b, p是整数
那么我们得到一个结论:k分解质因数后包含b的所有质因子。
那么就简单了, 分解, 去重, 乘起来, 转16进制。
可惜我tm没打高精度。
我以为:
假设多个b分解质因子后, 质因子都不相同, 那么乘积每次乘10^9。
一共1000个数, 那么就是10^12。
错了
是(10^9)^1000 = 10^9000
乘积
#include<bits/stdc++.h>
#pragma GCC optimize(2,3,"Ofast","inline","-fgcse","-fgcse-lm","-fipa-sra","-ftree-pre","-ftree-vrp","-fpeephole2","-ffast-math","-fsched-spec","unroll-loops","-falign-jumps","-falign-loops","-falign-labels","-fdevirtualize","-fcaller-saves","-fcrossjumping","-fthread-jumps","-funroll-loops","-fwhole-program","-freorder-blocks","-fschedule-insns","inline-functions","-ftree-tail-merge","-fschedule-insns2","-fstrict-aliasing","-fstrict-overflow","-falign-functions","-fcse-skip-blocks","-fcse-follow-jumps","-fsched-interblock","-fpartial-inlining","no-stack-protector","-freorder-functions","-findirect-inlining","-fhoist-adjacent-loads","-frerun-cse-after-loop","inline-small-functions","-finline-small-functions","-ftree-switch-conversion","-foptimize-sibling-calls","-fexpensive-optimizations","-funsafe-loop-optimizations","inline-functions-called-once","-fdelete-null-pointer-checks")
#define open(x) freopen(x".in", "r", stdin);freopen(x".out", "w", stdout)
#define mem(a, b) memset(a, b, sizeof(a))
#define mcy(a, b) memcpy(a, b, sizeof(a))
#define pf printf
#define sf scanf
#define fo(i, a, b) for( ll i = a; i <= b; ++i)
#define fown(i, a, b) for( ll i = a; i >= b; --i)
#define em(p, x) for(ll p=tail[x];p;p=e[p].fr)
#define ll long long
#define wt(a, c, d, s) fo(i, c, d) pf((s), a[i]); puts("")
#define rd(a, c, d) fo(iii, c, d) in((a)[i])
#define N 5050
#define inf 147483647
#define mod (ll)(1e9 + 7)
#define maxn (1e9+1)
using namespace std;
template<class T>
T in(T &x) {
x=0;
char ch = getchar(); ll f = 0;
while(ch < '0' || ch > '9') f |= ch == '-', ch = getchar();
while(ch >= '0' && ch <= '9') x = (x<<1) + (x<<3) + ch - '0', ch = getchar();
x = f ? -x : x;
return x;
}
ll n, i, j, ans;
ll a, b, A[30010], len;
set<ll> s;
ll ss(ll x) {
ll up = sqrt(x);
for(register ll j = 2 ; j <= up ; ++j) if(x % j == 0 ) return 0;
return 1;
}
const ll tp = 100;
struct bignum {
ll len, a[10000];
bignum() {mem(a, len = 0);}
ll val() {
ll ret = 0;
fown(i, len, 1) ret = ret * 10 + a[i];
return ret;
}
bignum operator * (ll x) {
bignum a = *this;
fo(i, 1, a.len) a.a[i] *= x;
fo(i, 1, a.len) {
a.a[i + 1] += a.a[i] / 10;
if(a.a[a.len + 1]) a.len++;
a.a[i] %= 10;
}
return a;
}
ll operator % (ll x) {
bignum a = *this;
ll r = 0;
fown(i, a.len, 1) {
r = r * 10 + a.a[i];
r = r % x;
}
return r;
}
bignum operator / (ll x) {
bignum a = *this;
ll r = 0;
fown(i, a.len, 1) {
r = r * 10 + a.a[i];
a.a[i] = r / x;
r = r % x;
}
while(a.a[a.len] == 0 && a.len) --a.len;
return a;
}
void operator = (ll x) {
while(x) {
this->a[++this->len] = x % 10;
x /= 10;
}
return ;
}
bool operator < (bignum x) {
ll lena = this->len, lenb = x.len;
if(lena < lenb) return 1;
if(lena > lenb) return 0;
fown(i, lena, 1) if(this->a[i] < x.a[i]) return 1; else if(this->a[i] > x.a[i])return 0;
return 0;
}
}sum;
ll check(bignum x) {
bignum tmp;
tmp = 16;
if(x < tmp) return 0;
return 1;
}
ll gcd(ll m, ll n) {
if(n == 0 ) return m;
return gcd(n, m % n);
}
char hexa(ll x) {
if(x < 10) return '0' + x;
else return 'A' + x - 10;
}
ll Ans[N];
int main() {
open("fraction");
in(n);
fo(i, 1, n) {
in(a), in(b);
ll g = gcd(a, b);
a /= g, b /= g;
ll up = sqrt(b);
ll tmp = b;
fo(i, 2, up) if(tmp % i == 0) {
A[++len] = i;
while(tmp % i == 0 )tmp/=i;
}
if(tmp > 1) A[++len] = tmp;
fo(i, 1, len) s.insert(A[i]);
len =0 ;
}
sum = 1;
set<ll>::iterator it;
for(it = s.begin() ; it != s.end() ; ++it)sum = sum * (*it);
ll cnt =0;
while(check(sum)) {
Ans[++cnt] = sum % 16;
sum = sum / 16;
}
Ans[++cnt] = sum.val();
fown(i, cnt, 1) pf("%c", hexa(Ans[i]));
return 0;
}