zoukankan      html  css  js  c++  java
  • 51 nod 1203 JZPLCM

    原题链接

    长度为N的正整数序列S,有Q次询问,每次询问一段区间内所有数的lcm(即最小公倍数)。由于答案可能很大,输出答案Mod 10^9 + 7。
     
    例如:2 3 4 5,询问[1,3]区间的最小公倍数为2 3 4的最小公倍数 = 12。
    Input
    第1行:两个整数,N, Q,中间用空格分隔,N为数列长度,Q为询问数量。(2 <= N, Q <= 50000)
    第2 - N + 1行:每行1个整数,对应数列中的元素(1 <= S[i] <= 50000)
    第N + 2 - N + Q + 1行:每行2个数,l, r,表示询问下标i在[l, r]范围内的S[i]的最小公倍数。(1 <= l <= r <= N)
    Output
    输出共Q行,对应询问区间的最小公倍数Mod 10^9 + 7。
    Input示例
    3 3
    123
    234
    345
    1 2
    2 3
    1 3
    Output示例
    9594
    26910
    1103310

    离线莫队,为了避免删数需要每次从当前块的终点跑到询问的左区间加数。
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define MN 50001
    using namespace std;
    int read_p,read_ca;
    inline int read(){
        read_p=0;read_ca=getchar();
        while(read_ca<'0'||read_ca>'9') read_ca=getchar();
        while(read_ca>='0'&&read_ca<='9') read_p=read_p*10+read_ca-48,read_ca=getchar();
        return read_p;
    }
    const int MOD=1e9+7;
    const int K=350;
    struct na{
        int l,r,k,p;
    }Q[MN];
    int n,m,A,p[MN],num=0,bo[MN],_p[MN][20],a[MN][20],Nu[MN],l,r,mmh[MN],L,R,t[MN],_t[MN],MMH,_MMH;
    inline bool cmp(na a,na b){return a.k==b.k?a.r<b.r:a.k<b.k;}
    inline int mi(int a,int b){
        int mmh=1;
        while (b){
            if (b&1) mmh=1LL*mmh*a%MOD;
            b>>=1;a=1LL*a*a%MOD;
        }
        return mmh;
    }
    inline void in(int x){for (register int i=1;i<=Nu[x];i++) if (a[x][i]>t[_p[x][i]]) MMH=1LL*MMH*mi(p[_p[x][i]],a[x][i]-t[_p[x][i]])%MOD,t[_p[x][i]]=a[x][i];}
    inline void work(int R,int x){
        register int i,j;_MMH=MMH;
        for (i=Q[x].l;i<=R;i++)
        for (j=1;j<=Nu[i];j++) if (a[i][j]>(_t[_p[i][j]]=_t[_p[i][j]]==0?t[_p[i][j]]:_t[_p[i][j]])) _MMH=1LL*_MMH*mi(p[_p[i][j]],a[i][j]-_t[_p[i][j]])%MOD,_t[_p[i][j]]=a[i][j];
        mmh[Q[x].p]=_MMH;
        for (i=Q[x].l;i<=R;i++)
        for (j=1;j<=Nu[i];j++) _t[_p[i][j]]=0;
    }
    int main(){
        register int i,j;
        for (i=2;i<MN;i++){
            if (!bo[i]) p[++num]=i,bo[i]=num;
            for (j=1;j<=num&&i*p[j]<MN;j++){
                bo[i*p[j]]=j;
                if (i%p[j]==0) break;
            }
        }
        n=read();m=read();
        for (i=1;i<=n;i++){
            A=read();
            while (A>1){
                if (bo[A]!=_p[i][Nu[i]]) _p[i][++Nu[i]]=bo[A];a[i][Nu[i]]++;A/=p[bo[A]];
            }
        }
        for (i=1;i<=m;i++)
        Q[i].l=read(),Q[i].r=read(),Q[i].k=(Q[i].l-1)/K,Q[i].p=i;
        sort(Q+1,Q+1+m,cmp);
        r=1;
        for (i=0;i<=(n-1)/K;i++){
            R=i*K+K;memset(t,0,sizeof(t));MMH=1;
            while (Q[r].k==i&&r<=m){
                if ((Q[r].r-1)/K==i) work(Q[r].r,r);else{
                    while(R<=Q[r].r) in(R),R++;
                    work(i*K+K-1,r);
                }
                r++;
            }
        }
        for (i=1;i<=m;i++) printf("%d
    ",mmh[i]);
    }
    View Code
    
    
    
     
  • 相关阅读:
    前端十万个为什么(之一):我们为什么需要npm?
    初识模块化开发工具:
    javascript 中的 let 作用域
    把汉字转换为html实体编码
    【小程序】开发过程问题整理
    【入门】正则表达式
    【CSS】面试知识整理
    【入门】Gulp 简单使用
    【入门】WebSocket 示例
    【JQ】$.ajax() 参数
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5673223.html
Copyright © 2011-2022 走看看