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;
}
原文地址:https://www.cnblogs.com/zbr162/p/11822429.html