那天我五个小时时间基本都用来研究这个题目了,结果还是没出来。。。。
下来后找到了别人的代码看了看,研究了一段时间,明白他的思想但是还是不明白代码的具体道理。
我想到一个可以用二分查找来节约时间的方法,于是写了下来, 终于A了,my god...
以下是我的代码(代码写的不是很科学):
#include <stdio.h>#include <string.h>int prim[30]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};//100内的素数long long num[30]; //100内素数对应的指数long long power(int a, long long p) //计算p的阶层里有多少个素数a{ long long res=0; while (p) { p /= a; res += p; } return res;}long long binary(int i, long long from, long long to) //用二分查找满足素数prim[i]的最小值{ long long mid = (from+to)/2; if (to-from == 1) { mid = power(prim[i], from); if (mid >= num[i]) return from; else return to; } if (power(prim[i], mid) < num[i]) return binary(i, mid, to); else return binary(i, from, mid);}int main(){ int T, n, i, j; long long a, b, p, ans, max; scanf("%d", &T); while (T--) { memset(num, 0, sizeof(num)); scanf("%d", &n); for (i=0; i<n; i++) { scanf("%I64d %I64d", &a, &b); for (j=0; j<25; j++) { while (a>0 && a%prim[j]==0) { num[j] += b; a /= prim[j]; } } } max = 0; for (i=0; i<25; i++) if (num[i]) { p = prim[i]; while (power(prim[i], p) < num[i]) //先以指数速度查找大概范围 p *= prim[i]; ans = binary(i, p/prim[i], p); //再用二分查找精确最小值位置 if (ans > max) max = ans; } printf("%I64d/n", max); }}
别人的代码,估计有科学道理的,只是我不知道而已:
#include <stdio.h>#include <math.h>#include <string.h>#include <iostream>using namespace std;__int64 c[200], re[200], p;__int64 powerp(__int64 a, __int64 p){ __int64 tmp=a; for (int i=2; i<=p; ++i) tmp *= a; return (tmp-1)/(a-1);}void work(){ memset(c, 0, sizeof(c)); int n; cin >> n; for (int i=0; i<n; ++i) { __int64 x, y; cin >> x >> y;g for (int j=2; j<=150; ++j) { while (x > 0 && x % j == 0) { c[j] += y; x /= j; } } } __int64 ans = 0; for (int i=2; i<=150; ++i) if (c[i] > 0) { __int64 p = 1; while (powerp(i, p) <= c[i]) ++p; __int64 t = 0; while (p) { t = t*i + c[i]/powerp(i, p); c[i] = c[i]%powerp(i, p); --p; } t = t*i; if (t > ans) ans = t; } cout << ans << endl;}int main(){ int test; cin >> test; while (test--) work();}