先考虑离线版本:
LCM可以转化为区间数包含每个 [质因子,所有数含这个质因子个数的最大值] 的乘积,比如区间2,4,8,18质因子2 最多的数是8,有三个,所以2对于LCM的贡献为2^3 = 8. 而3的贡献为3^2 = 9 所以LCM 为:72
所以我们可以考虑枚举右端点r,每次维护一颗线段树,区间[x,r],表示 区间[x,r]的LCM, 而区间[x,r]的值恰好是区间值的乘积。
(因为区间乘积可以用线段树维护,而LCM不行),显然我们可以这样维护:
添加一个数: ,
枚举每个质因子p,把 pi ^ ci 单点乘到r,这样的话总区间质因子pi的个数就多了ci个,我们需要在前面减去pi使得[x,r]区间质因子p的最大值不会超。
比如:
6 4 8 18
先加入6,线段树各节点的值为:
6 1 1 1
再加入4:
3 4 1 1
再加入8
3 1 8 1
再加入18
1 1 4 18
这样保证了每个枚举的r,区间[l,r]的乘积均为区间[l,r]的LCM, 可以仔细想一下这个过程。
类比线段树离线处理区间种类数,来理解这个做法!
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
//#define m (l+r)/2
#define pb push_back
typedef pair<int,int> pii;
const double PI= acos(-1.0);
const int M = 2e5+7;
const int mod = 1e9+7;
struct node{
int l,r,id,ans;
}p[M];
bool c