NEU1694: Primorial vs LCM

来源:互联网 发布:淘宝联盟发送朋友圈 编辑:程序博客网 时间:2024/06/06 01:27

链接:http://acm.neu.edu.cn/hustoj/problem.php?id=1694

题意:给定多个n,求LCM(1~n)/pi{pi为1~n中的素数}。

分析:因为n太大有10^14,我们得观察一些性质才行。因为要求的是最小公倍数然后除掉所有的质数,这里很明显大于sqrt(n)的素数就没意义了,因为最后答案中留下的只能是指数大于1的素数。那么我们就将素数范围缩小到了10^7,然后我们再来看看有什么其他的性质,我们会知道素数p在答案中的贡献应该是p^k<=n<p^(k+1)时的p^(k-1),并且明显会有小质数的贡献质数k>=大质数的k,有了这些我们就能处理出2^2,2^3,3^3等等这些数了,比如:(4,2),(8,2),(9,3),(16,2),(25,5)。。。假设n=10,那我们找到小于它的第一个值(9,3)那么答案就是2*2*3啦,当n=26时找到(25,5)答案就是2*2*3*2*5啦。详见代码。

代码:

#include<map>#include<set>#include<cmath>#include<queue>#include<bitset>#include<math.h>#include<cstdio>#include<vector>#include<string>#include<cstring>#include<iostream>#include<algorithm>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int N=10000010;const int MAX=1000000100;const int mod=100000000;const int MOD1=1000000007;const int MOD2=1000000009;const double EPS=0.00000001;typedef long long ll;const ll MOD=1000000007;const int INF=1000000010;typedef double db;typedef unsigned long long ull;struct node {    ll x,y,z;    node(){}    node(ll x,ll y):x(x),y(y){}    bool operator < (const node a) const{        return x<a.x;    }}f[700000];int g,a[N],q[N];void deal(ll n) {    int i,j,k=0;    ll mul;    memset(q,0,sizeof(q));    for (i=2;i<=n;i++) {        if (!q[i]) a[++k]=i;        for (j=1;j<=k;j++) {            if ((ll)a[j]*i>n) break ;            q[a[j]*i]=1;            if (i%a[j]==0) break ;        }    }    n=n*n;    for (i=1;i<=k;i++) {        mul=(ll)a[i]*a[i];        f[++g]=node(mul,a[i]);        while (log(mul)+log(a[i])<=log(n)) {            f[++g]=node(mul*a[i],a[i]);mul*=a[i];        }    }    sort(f+1,f+g+1);f[1].z=2ll;    for (i=2;i<=g;i++) f[i].z=f[i-1].z*f[i].y%MOD;}ll getans(ll n) {    if (n<4) return 1ll;    if (n>=f[g].x) return f[g].z;    int l=1,r=g,mid=(l+r)>>1;    while (l+1<r)    if (f[mid].x>n) { r=mid;mid=(l+r)>>1; }    else { l=mid;mid=(l+r)>>1; }    return f[l].z;}int main(){    int i,t,ca;    ll n,ans;    deal(10000000ll);    scanf("%d", &t);    for (ca=1;ca<=t;ca++) {        scanf("%lld", &n);        printf("Case %d: %lld\n", ca, (getans(n)+MOD)%MOD);    }    return 0;}


0 0
原创粉丝点击