LOJ 1289 求出前n个数的最小公倍数

n<=10^8, 答案要模2^32.

思路: 这道题开始想了很多东西都不行。 后来突然想到了方法。

手下我打出10^8的素数表。 如果用一般的方法肯定是不行的。 这里我用区间素数求法。将10^8分成100段。 这样的话就可以打出素数表。

打出素数表之后,我在求出前i项的最小公倍数。同样数组还是开不够。这样的话我还是将10^8分成1000000段,

f【1】表示前100个数的最小公倍数,f【2】是前200个。。。。。

最后给出一个n,先求出f[n/100],在对剩下的部分处理就行。

AC代码:

View Code
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <string>
  4 #include <cstring>
  5 #include <queue>
  6 #include <cmath>
  7 #include <algorithm>
  8 using namespace std;
  9 typedef unsigned long long ULL;
 10 
 11 const int N = 6010000;
 12 const ULL P = 1ULL<<32, M = 100000000;
 13 int p[N], num;
 14 ULL f[1010000], n;
 15 bool np[N] = {0};
 16 void getprime(int L, int U)
 17  {
 18      memset(np, 0, sizeof(np));
 19      int su = sqrt((double)U), d=U-L+1;
 20      for(int i=L%2; i<d; i+=2)
 21       np[i] = 1;
 22      for(int i=3; i<=su; i+=2)
 23       {
 24           int j = L/i*i;
 25           if(j<L) j+=i;
 26           if(j == i) j+=i;
 27           j = j-L;
 28           for(; j<d;j+=i)
 29            np[j] = 1;
 30       }
 31      if(L <= 1) np[1-L] = 1;
 32      if(L <= 2) np[2-L] = 0;
 33      for(int i=0; i<d; i++)
 34       if(!np[i])
 35        p[num++] = i+L;
 36  }
 37 
 38 void getp()
 39  {
 40      for(int i=0; i<100; i++)
 41       {
 42           getprime(i*1000000+1, (i+1)*1000000);
 43       }
 44      for(int i=0;i <= 1000000; i++)
 45       f[i] = 1;
 46      ULL now;
 47      for(int i=0; i<num; i++)
 48       {
 49           now = p[i];
 50           while(now <= M)
 51            {
 52                f[now/100+1] *= p[i];
 53                now *= p[i];
 54            }
 55       }
 56      for(int i=1; i<=1000000; i++)
 57       {
 58           f[i] *= f[i-1];
 59           if(f[i]>= P) f[i] %= P;
 60       }
 61  }
 62 
 63 ULL get(ULL n)
 64  {
 65      for(int i=0; i<num &&((ULL)p[i])*p[i] <= n; i++)
 66       {
 67           if(n % p[i] == 0)
 68            {
 69                while(n%p[i] == 0)
 70                 n /= p[i];
 71                if(n == 1) return p[i];
 72                return 1;
 73            }
 74       }
 75     return n;
 76  }
 77 
 78 void solve()
 79  {
 80      ULL ans = f[n/100]%P;
 81      for(ULL i=max(n/100*100,1ULL); i<=n; i++)
 82       {
 83           ans *= get(i);
 84           if(ans >= P) ans %= P;
 85       }
 86      printf("%llu\n", ans);
 87  }
 88 
 89 int main()
 90  {
 91      getp();
 92      int t;
 93      scanf("%d", &t);
 94      for(int i=1; i<=t; i++)
 95       {
 96           scanf("%llu", &n);
 97           printf("Case %d: ",i);
 98           solve();
 99       }
100      return 0;
101  }

 

 

posted @ 2012-10-13 13:51  Gu Feiyang  阅读(362)  评论(0)    收藏  举报