zoukankan      html  css  js  c++  java
  • LCM [树状数组, HH的项链]

    LCMLCM

    NMLCM1e9+7.给你一个长度为 N 的数列,有 M 次询问,每次询问一段区间的 LCM 模 1e9+7 的值 .

    1N200000 1M200000 1Ai10000001 ≤ N ≤ 200000 1 ≤ M ≤ 200000 1 ≤ Ai ≤ 1000000


    color{red}{正解部分}

    类似 ‘HH的项链’ 的做法,

    将所有询问离线, 按 右端点 从小到大 排序, 然后 从左向右 枚举 ii,

    首先对当前位置的 A[i]A[i] 进行 质因数 分解, 记 last[pk]last[p^k] 表示 pkp^k 这个因子在 ii 前面最晚出现的位置,
    使用 树状数组 维护 前缀积, 若 A[i]A[i] 含有质因子 pmp^m, 则对 last[p1],last[p2]...last[pm]last[p^1], last[p^2]...last[p^m] 位置上的值 pp, 使 last[pk]=ilast[p^k]=i, 最后在 ii 位置上 mmpp,


    color{red}{实现部分}

    #include<bits/stdc++.h>
    #define reg register
    
    const int maxn = 1e6 + 5;
    const int mod = 1e9 + 7;
    
    int N;
    int M;
    int pcnt;
    int p[maxn];
    int A[maxn];
    int fm[maxn];
    int Ans[maxn];
    int last[maxn];
    
    bool vis[maxn];
    
    void sieve(){
            for(reg int i = 2; i < maxn; i ++){
                    if(!vis[i]) p[++ pcnt] = i, fm[i] = i;
                    for(reg int j = 1; j <= pcnt && i*p[j] < maxn; j ++){
                            vis[i*p[j]] = 1; fm[i*p[j]] = p[j];
                            if(i % p[j] == 0) break ;
                    }
            }
    }
    
    int Ksm(int a, int b){int s=1;while(b){ if(b&1)s=1ll*s*a%mod;a=1ll*a*a%mod;b>>=1; }return s;}
    
    struct Que{ int l, r, id; } que[maxn];
    
    struct Bit_Tree{
            int v[maxn], lim;
            void Add(int k, int x){ while(k<=lim)v[k]=1ll*v[k]*x%mod,k+=k&-k; }
            int Query(int k){ if(k<=0) return 1; int s=1; while(k)s=1ll*s*v[k]%mod,k-=k&-k; return s; }
    } bit_t;
    
    bool cmp(Que a, Que b){ return a.r < b.r; }
    
    int main(){
            sieve();
            scanf("%d%d", &N, &M); bit_t.lim = N;
            for(reg int i = 1; i <= N; i ++) scanf("%d", &A[i]), bit_t.v[i] = 1;
            for(reg int i = 1; i <= M; i ++) scanf("%d%d", &que[i].l, &que[i].r), que[i].id = i;
            std::sort(que+1, que+M+1, cmp); int t = 1;
            for(reg int i = 1; i <= N; i ++){
                    int x = A[i];
                    while(x > 1){
                            int k = 1, p = fm[x];
                            while(x%p == 0){
                                    x /= p, k *= p;
                                    if(last[k]) bit_t.Add(last[k], Ksm(p, mod-2));
                                    last[k] = i; bit_t.Add(i, p);
                            }
                    }
                    while(i == que[t].r) Ans[que[t].id] = 1ll*bit_t.Query(que[t].r)*Ksm(bit_t.Query(que[t].l-1), mod-2)%mod, t ++;
            }
            for(reg int i = 1; i <= M; i ++) printf("%d
    ", Ans[i]);
            return 0;
    }
    
  • 相关阅读:
    NYOJ 267(郁闷的C小加(二)) 后缀表达式求值
    NYOJ 104 最大和
    NYOJ 654(01包优化)
    CMM (度量Metrics)
    CMM (软件工程与集成产品开发)
    CMM (同行评审Peer Review)
    Software Engineering (软件工程简述)
    CMM (需求管理Requirement Management)
    CMM (项目计划与跟踪Project Management)
    Symbian(Carbide IDE开发环境搭建)
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822429.html
Copyright © 2011-2022 走看看