数论的题做的很少,这道题本来不难,结果在五个小时内还是没做出来。所有a[i]分解质因子,并累计0到100中所有质因子出现的次数存入num数组中。X!要能被M整除,那么在M中出现的所有的质因子就应该在x!中出现并且出现的次数不少于在M中出现的次数。然后二分答案。
有一个计算公式:
LL cal(LL i, LL x)
{
LL ret = 0;
while(x)
{
x /= i;
ret += x;
}
return ret;
}
可以求出i在X!中出现的次数。
/*Accepted 3641 0MS 252K 1461 B C++ Yu*/ #include<stdio.h> #include<string.h> #include<stdlib.h> #include<algorithm> using namespace std; typedef __int64 LL; const int MAXN = 105; LL a, b, ans; LL num[MAXN]; int n; void pre(LL a, LL b) { int i, cnt; for(i = 2; i * i <= a; i ++) { cnt = 0; while(a % i == 0) { a /= i; cnt ++; } num[i] += cnt * b; if(a == 1) break; } if(a > 1) num[a] += b; //此时,a是素数 } LL cal(LL i, LL x) { LL ret = 0; while(x) { x /= i; ret += x; } return ret; } bool judge(LL x) { int i; for(i = 1; i <= 100; i ++) { if(num[i]) { LL t = cal(i, x); if(t < num[i]) return false; } } return true; } int main() { int T, i; scanf("%d", &T); while(T --) { scanf("%d", &n); memset(num, 0, sizeof num); for(i = 0; i < n; i ++) { scanf("%I64d%I64d", &a, &b); pre(a, b); } LL left = 0, right = (LL(1)) << 60; while(left <= right) { LL mid = (left + right) >> 1; if(judge(mid)) { ans = mid; right = mid - 1; } else left = mid + 1; } printf("%I64d\n", ans); } return 0; }
浙公网安备 33010602011771号