FOJ Problem 1753
解法:筛素数。
但是不知道为什么用unsigned long long一直wa,而unsigned __int64可以ac。怨念啊= =
先筛选出100000以内的所有素数,约10000个。对所有的ni,mi,分别求出ni,ni-mi,mi的阶乘含有的每个素因子的个数。然后就简单了吧。还有一个剪枝的地方,见注释。
提交了10几遍- -
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <cstdlib> #include <ctime> #include <cmath> #include <string.h> #include <queue> #include <string> #include <algorithm> using namespace std; const int N = 100005; const int M = 10000; const int INF = 1<<29; bool is[N]; int prm[M]; int getprm(int n){ int i, j, k = 0; int s, e = (int)(sqrt(0.0 + n) + 1); memset(is, 1, sizeof(is)); prm[k++] = 2; is[0] = is[1] = 0; for (i = 4; i < n; i += 2) is[i] = 0; for (i = 3; i < e; i += 2) if (is[i]) { prm[k++] = i; for (s = i * 2, j = i * i; j < n; j += s) is[j] = 0; // 因为j是奇数,所以+奇数i后是偶数,不必处理! } for ( ; i < n; i += 2) if (is[i]) prm[k++] = i; return k; // 返回素数的个数 } int t, mi[155], ni[155], k; int getx(int n,int x)//非递归写法 { int ret = 0; while (n){ ret += n/x; n /= x; } return ret; } int a, b[10000]; unsigned __int64 solve(){ for (int i = 0; i <= k; i++) b[i] = INF; for (int i = 0; i < t; i++){ for (int j = 0; j < k; j++){ //不加这个会超时- - if (!b[j])continue; a=getx(ni[i],prm[j])-getx(ni[i]-mi[i],prm[j])-getx(mi[i],prm[j]); b[j]=min(b[j],a); } } unsigned __int64 sum = 1; for (int j = 0; j < k; j++) if (b[j]) for (int l=0; l<b[j]; l++) sum *= (unsigned __int64)prm[j]; return sum; } int main(){ k = getprm(N - 3); while (scanf("%d", &t) != EOF){ for (int i = 0; i < t; i++) scanf("%d%d", &ni[i], &mi[i]); printf("%I64u\n", solve()); } return 0; }