题目链接:http://lightoj.com/volume_showproblem.php?problem=1289
题意:求LCM(1, 2, 3, ... , n)%(1<<32), (1<n<=1e8);
LCM(1, 2, 3, ... , n) = n以内所有素数的最高次幂之积,例如15: 23*32*5*7*11*13 = 36360360;
为了防止TLE所以,要有一个数组表示前缀积,但是直接开LL会MLE是,因为有个%1<<32刚好是unsigned int之内,可以开int的数组;
关于求1e8内的素数表,用bool类型也会MLE的,所以可以使用bitset类型;
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #include <bitset> #include <iostream> #include <time.h> typedef long long LL; using namespace std; const int N = 1e8+1; const double eps = 1e-10; const int INF = 0x3f3f3f3f; const LL mod = (1ll<<32); int k, p[6000005]; unsigned int Mul[6000005]; bitset<N> f; void Init() { f.reset(); for(int i=2; i<N; i++) { if(f[i]) continue; p[k++] = i; for(int j=i+i; j<N; j+=i) f[j] = 1; } } int main() { int T, t = 1; scanf("%d", &T); Init(); Mul[0] = p[0]; for(int i=1; i<k; i++) Mul[i] = Mul[i-1]*p[i]; while(T --) { int n; scanf("%d", &n); int pos = upper_bound(p, p+k, n)-p - 1; LL ans = Mul[pos]; for(int i=0; i<k && (LL)p[i]*p[i]<=n; i++) { LL num = 1; while(num <= n) num *= p[i]; if(num%(p[i]*p[i]) == 0) num /= (p[i]*p[i]); ans = ans*num%mod; } printf("Case %d: %lld ", t++, ans); } return 0; }
还有一种比较快一点的方法:
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #include <bitset> #include <iostream> #include <time.h> typedef long long LL; using namespace std; const int N = 1e8+1; const double eps = 1e-10; const int INF = 0x3f3f3f3f; const LL mod = (1ll<<32); int k = 0, p[6000005], f[N/32+5]; unsigned int Mul[6000005]; void Init() { p[k++] = 2; for(int i=3; i<N; i+=2) { if(f[i/32]&(1<<((i/2)%16))) continue; p[k++] = i; for(int j=3*i; j<N; j+=2*i) f[j/32] |= (1<<((j/2)%16)); } ///printf("%d ", k); } int main() { int T, t = 1; scanf("%d", &T); Init(); Mul[0] = p[0]; for(int i=1; i<k; i++) Mul[i] = Mul[i-1]*p[i]; while(T --) { int n; scanf("%d", &n); int pos = upper_bound(p, p+k, n)-p - 1; LL ans = Mul[pos]; for(int i=0; i<k && (LL)p[i]*p[i]<=n; i++) { LL num = 1; while(num <= n) num *= p[i]; if(num%(p[i]*p[i]) == 0) num /= (p[i]*p[i]); ans = ans*num%mod; } printf("Case %d: %lld ", t++, ans); } return 0; }