Light OJ 1289 LCM from 1 to n
題意:
輸入
t(t≤10000) 組樣例,
每組樣例包含一個n(2≤n≤108) ,
求lcm(1,2,3,…,n) .
思路:
計算
我們設
g(n)=lcm(1,2,3,…,n)
如果n=pk,g(n)=g(n−1)∗p .
否則g(n)=g(n−1) .
由於多組樣例直接求會TLE,如果預處理
如何把握好時空上的取捨是這題的有趣之處,內存多給點會死啊!
首先要預處理 n 以內的素數,用一般篩法會用到
由於
按理來說以上步驟已經極度優化了複雜度,如果放codeforces早過了。。但依然是MLE 真是日了狗,大概還需要砍掉一半的空間。
剛纔的算法時間複雜度是預處理
於是我們不存儲任何
這樣的時間複雜度爲預處理
主要空間大小有一個
終於理解C/C++爲啥大行於ACM,操作內存簡直無情啊!
ps.這題要求要模除
pss.原來我比較喜歡用vector來存儲素數表,但這題這麼做會MLE,vector動態更新大小條件是佔用大概1.5倍乃至兩倍內存,還是那句話。。時間空間卡太緊的時候慎用STL。。
代碼:
/*
* @author FreeWifi_novicer
* language : C++/C
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
using namespace std;
#define clr( x , y ) memset(x,y,sizeof(x))
#define cls( x ) memset(x,0,sizeof(x))
#define mp make_pair
#define pb push_back
typedef long long lint;
typedef long long ll;
typedef long long LL;
const int maxn = 1e8 + 5 ;
const int pnum = 5761460 ;
bitset<maxn>noprime ;
unsigned int mul[pnum] ;
int p[pnum] , len ;
int sieve(){
noprime.reset() ;
for( int i = 2 ; i * i <= maxn ; i++ ){
if( !noprime[i] ){
for( int j = i * i ; j <= maxn ; j += i ){
noprime[j] = 1 ;
}
}
}
int k = 0 ;
for( int i = 2 ; i <= maxn ; i++ )
if( !noprime[i] ) p[k++] = i ;
return k ;
}
void init_lcm(){
len = sieve() ;
mul[0] = p[0] ;
for( int i = 1 ; i < len ; i++ )
mul[i] = mul[i-1] * p[i] ;
}
void solve( int n ){
int pos = lower_bound( p , p + len , n ) - p ;
if( p[pos] != n ) pos-- ;
unsigned int ans = mul[pos] ;
for( int i = 0 ; p[i] * p[i] <= n ; i++ )
{
int tmp = p[i] ;
int tmp2 = p[i] * p[i] ;
while( tmp2 / tmp == p[i] && tmp2 <= n )
{
tmp = tmp * p[i] ;
tmp2 = tmp2 * p[i] ;
}
ans = ans * ( tmp / p[i] ) ;
}
cout << ans << endl ;
}
int main(){
// freopen("input.txt","r",stdin);
int t ; cin >> t ; int kase = 1 ;
init_lcm() ;
while( t-- ){
int n ;
cin >> n ;
printf( "Case %d: " , kase++ ) ;
solve( n ) ;
}
return 0;
}