求解 所有子区间的最大lcmlcm %mod 的乘积
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <cmath>
using namespace std;
typedef long long LL;
const int mod = 1e9 + 7;
const int mod_1 = mod - 1;
const int MAXN = 100003;
const int Sqr = (int)sqrt(MAXN) + 1;
struct Io
{
char A[MAXN * 4],*L,*R;
int count;
Io()
{
L = R = A;
count = MAXN * 4;
}
void Io_fread()
{
L = A;
R = A + fread(A, sizeof(char), count, stdin);
}
int read()
{
int tmp = 0;
if (L == R)
{
Io_fread();
if (L == R)return 0;
}
while (*L<'0'||*L>'9')
{
L++;
if (L == R)
{
Io_fread();
if (L == R)return 0;
}
}
while (*L >= '0'&&*L <= '9')
{
tmp = tmp * 10 + (*L - '0');
L++;
if (L == R)
{
Io_fread();
if (L == R)return tmp;
}
}
return tmp;
}
}I;
int used[MAXN];
int buf[MAXN];
int G[MAXN];
int tmp[MAXN];
int tmp2[MAXN];
int nxt[MAXN];
int fst[MAXN];
int bnxt[MAXN];
int bfst[MAXN];
int queue[MAXN];
int stk[MAXN];
int *wnxt = tmp, *wfst = tmp2, *AL = tmp, *AR = tmp2, *C = used;
int ans = 1;
struct node
{
int c[2];
int L, R;
node()
{
L = R = c[0] = c[1] = 0;
}
};
struct Decare
{
node A[MAXN];
int root;
int deep;
Decare()
{
root = 0;
deep = 1;
}
void _insert(int key, int inof)
{
if (inof == 0)
{
root = deep++;
tmp[root] = key;
return;
}
while (inof)
{
if (tmp[inof] >= key)
{
tmp[deep] = key;
G[deep] = inof;
A[deep].c[0] = A[inof].c[1];
A[inof].c[1] = deep;
G[A[deep].c[0]] = deep;
deep++;
return;
}
inof = G[inof];
}
tmp[deep] = key;
A[deep].c[0] = root;
G[root] = deep;
root = deep++;
}
void insert(int key)
{
_insert(key, deep - 1);
}
void BFS(int root)
{
memset(tmp, 0, sizeof tmp);
int l = 0, r = 1;
stk[0] = root;
while (l < r)
{
int v = stk[l++];
if (A[v].c[0]) stk[r++] = A[v].c[0];
if (A[v].c[1]) stk[r++] = A[v].c[1];
}
int n = r;
while (r--)
{
int v = stk[r];
tmp[v] ++;
tmp[G[v]] += tmp[v];
}
tmp[0] = 0;
l = 0; r = 1;
A[root].L = 1;
A[root].R = n;
A[0].L = 1;
A[0].R = 0;
while (l<r)
{
int v = stk[l++];
A[A[v].c[0]].L = A[v].L;
A[A[v].c[0]].R = A[A[v].c[0]].L + tmp[A[v].c[0]] - 1;
A[A[v].c[1]].L = A[A[v].c[0]].R + 2;
A[A[v].c[1]].R = A[A[v].c[1]].L + tmp[A[v].c[1]] - 1;
if (A[v].c[0]) stk[r++] = A[v].c[0];
if (A[v].c[1]) stk[r++] = A[v].c[1];
}
memset(tmp, 0, sizeof tmp);
memset(G, 0, sizeof G);
A[0].L = 1;
A[0].R = 0;
}
}D;
int Pow(int a, int b)
{
int tmp = 1;
while (b)
{
if (b & 1)
tmp = (LL)tmp*a%mod;
a = (LL)a*a%mod;
b >>= 1;
}
return tmp;
}
int A[MAXN];
int find_nxt(int k, int B)
{
int top = -1, d = k;
while (bnxt[d] <= B)
{
stk[++top] = d;
d = bnxt[d];
}
while (top>-1)
{
int x = stk[top--];
if (bnxt[x] == nxt[x])wnxt[x] = A[x] * (bnxt[x] - x);
wnxt[x] += wnxt[bnxt[x]];
bnxt[x] = d;
}
return wnxt[k] + (B - d + 1)*A[d];
}
int find_fst(int k, int B)
{
int top = -1, d = k;
while (bfst[d] >= B)
{
stk[++top] = d;
d = bfst[d];
}
while (top>-1)
{
int x = stk[top--];
if (bfst[x] == fst[x]) wfst[x] = A[x] * (x - bfst[x]);
wfst[x] += wfst[bfst[x]];
bfst[x] = d;
}
return wfst[k] + (d - B + 1)*A[d];
}
void BFS_1(int root, int P)
{
int l = 0, r = 1;
queue[0] = root;
while (l < r)
{
int v = queue[l++];
if (D.A[v].c[0])queue[r++] = D.A[v].c[0];
if (D.A[v].c[1])queue[r++] = D.A[v].c[1];
}
while (r--)
{
int v = queue[r];
int *c = D.A[v].c;
int L = D.A[v].L;
int R = D.A[v].R;
if (L == R)
{
G[P] = (G[P] + (LL)A[L] * buf[L] % (mod_1)) % mod_1;
continue;
}
int mid = (c[0]) ? D.A[c[0]].R + 1 : D.A[c[1]].L - 1;
if ((D.A[c[0]].R - D.A[c[0]].L + 1)<(D.A[c[1]].R - D.A[c[1]].L + 1))
{
for (int i = mid; i >= L; i = fst[i])
{
if (nxt[i] <= R)
{
int bk = fst[i] < L ? L : fst[i] + 1;
G[P] += ((LL)(i - bk + 1)*(nxt[i] - mid) % (mod - 1))*((LL)A[i] * buf[mid] % (mod - 1)) % (mod - 1);
if (G[P] >= mod - 1)G[P] -= mod - 1;
G[P] += (LL)(i - bk + 1)*(buf[mid]) % (mod - 1)*find_nxt(nxt[i], R) % (mod - 1);
if (G[P] >= mod - 1)G[P] -= mod - 1;
}
else
{
int bk = fst[i]<L ? L : fst[i] + 1;
G[P] += ((LL)(i - bk + 1)*(R - mid + 1) % (mod - 1))*((LL)A[i] * buf[mid] % (mod - 1)) % (mod - 1);
if (G[P] >= mod - 1)G[P] -= mod - 1;
}
}
}
else
{
for (int i = mid; i <= R; i = nxt[i])
{
if (fst[i] >= L)
{
int bk = nxt[i]>R ? R : nxt[i] - 1;
G[P] += ((LL)(bk - i + 1)*(mid - fst[i]) % (mod - 1))*((LL)A[i] * buf[mid] % (mod - 1)) % (mod - 1);
if (G[P] >= mod - 1)G[P] -= mod - 1;;
G[P] += (LL)(bk - i + 1)*buf[mid] % (mod - 1)*find_fst(fst[i], L) % (mod - 1);
if (G[P] >= mod - 1)G[P] -= mod - 1;
}
else
{
int bk = nxt[i]>R ? R : nxt[i] - 1;
G[P] += ((LL)(bk - i + 1)*(mid - L + 1) % (mod - 1))*((LL)A[i] * buf[mid] % (mod - 1)) % (mod - 1);
if (G[P] >= mod - 1)G[P] -= mod - 1;
}
}
}
}
}
void BFS_2(int root)
{
int l = 0, r = 1;
queue[0] = root;
while (l < r)
{
int v = queue[l++];
if (D.A[v].c[0])queue[r++] = D.A[v].c[0];
if (D.A[v].c[1])queue[r++] = D.A[v].c[1];
}
while (r--)
{
root = queue[r];
int *c = D.A[root].c;
int L = D.A[root].L;
int R = D.A[root].R;
if (L == R)
{
G[A[buf[L]]] = (G[A[buf[L]]] + buf[L]) % mod_1;
AL[root] = AR[root] = C[root] = A[buf[L]];
continue;
}
int mid = (c[0]) ? D.A[c[0]].R + 1 : D.A[c[1]].L - 1;
int tot = (LL)(mid - L + 1)*(R - mid + 1) % mod_1;
if ((D.A[c[0]].R - D.A[c[0]].L) < (D.A[c[1]].R - D.A[c[1]].L))
{
AR[root] = (LL)AR[c[0]] * AR[c[1]] % mod;
AL[root] = (LL)AL[c[0]] * AL[c[1]] % mod;
C[root] = (LL)C[c[0]] * C[c[1]] % mod;
for (int i = mid; i >= L; i--)
{
int &bk = nxt[i];
if (bk <= mid)continue;
int a = A[buf[i]];
if (bk > R)
{
G[a] += (LL)buf[mid] * (i - L + 1) % mod_1*(R - mid + 1) % mod_1;
if (G[a] >= mod_1)G[a] -= mod_1;
AR[root] = (LL)AR[root] * Pow(A[buf[i]], R - mid + 1) % mod;
int b = (i == mid) ? (fst[i]<L ? L : fst[i] + 1) : mid + 1;
AL[root] = (LL)AL[root] * Pow(A[buf[i]], mid - b + 1) % mod;
if ((i == mid && fst[i] >= L) || i != mid)
C[c[0]] = (LL)C[c[0]] * Pow(A[buf[i]], mod - 2) % mod;
}
else
{
//bk<=R
int b = tot - (LL)(mid - i)*(bk - mid) % mod_1;
if (b < 0)b += mod_1;
G[a] += (LL)buf[mid] * b % mod_1;
if (G[a] >= mod_1)G[a] -= mod_1;
AR[c[1]] = (LL)AR[c[1]] * Pow(A[buf[i]], (LL)(mod - 2)*(R - bk + 1) % mod_1) % mod;
C[c[1]] = (LL)C[c[1]] * Pow(A[buf[i]], mod - 2) % mod;
if (i != mid)
{
C[c[0]] = (LL)C[c[0]] * Pow(A[buf[i]], mod - 2) % mod;
C[root] = (LL)C[root] * Pow(A[buf[i]], mod - 2) % mod;
AL[root] = (LL)AL[root] * Pow(A[buf[i]], mid - i) % mod;
}
else
{
C[c[0]] = (LL)C[c[0]] * (fst[i]<L ? 1 : Pow(A[buf[i]], mod - 2)) % mod;
C[root] = (LL)C[root] * (fst[i]<L ? 1 : Pow(A[buf[i]], mod - 2)) % mod;
AL[root] = (LL)AL[root] * Pow(A[buf[i]], mid + 1 - ((fst[i]<L) ? L : fst[i] + 1)) % mod;
}
AR[root] = (LL)AR[root] * Pow(A[buf[i]], bk - mid) % mod;//
}
}
ans = (LL)ans*Pow(AR[c[1]], (LL)(mid - L + 1)*buf[mid] % (mod - 1)) % mod;
AL[root] = (LL)AL[root] * Pow(C[c[1]], mid - L + 1) % mod;
if (nxt[mid]>R&&fst[mid]<L) C[root] = (LL)C[root] * A[buf[mid]] % mod;
}
else
{
AR[root] = (LL)AR[c[0]] * AR[c[1]] % mod;
AL[root] = (LL)AL[c[0]] * AL[c[1]] % mod;
C[root] = (LL)C[c[0]] * C[c[1]] % mod;
for (int j = mid; j <= R; j++)
{
int &bk = fst[j];
int a = A[buf[j]];
if (bk >= mid)continue;
if (bk < L)
{
G[a] += (LL)buf[mid] * (mid - L + 1) % (mod - 1)*(R - j + 1) % (mod - 1);
if (G[a] >= mod - 1)G[a] -= mod - 1;
AL[root] = (LL)AL[root] * Pow(A[buf[j]], mid - L + 1) % mod;
int b = (j == mid) ? (nxt[j] <= R ? nxt[j] - 1 : R) : mid - 1;
AR[root] = (LL)AR[root] * Pow(A[buf[j]], b - mid + 1) % mod;
if ((j == mid&&nxt[j] <= R) || j != mid)
C[c[1]] = (LL)C[c[1]] * Pow(A[buf[j]], mod - 2) % mod;
}
else
{
int b = tot - (LL)(mid - bk)*(j - mid) % mod_1;
if (b < 0)b += mod_1;
G[a] += (LL)buf[mid] * b % mod_1;
if (G[a] >= mod - 1)G[a] -= mod_1;
AL[c[0]] = (LL)AL[c[0]] * Pow(A[buf[j]], (LL)(bk - L + 1)*(mod - 2) % mod_1) % mod;
C[c[0]] = (LL)C[c[0]] * Pow(A[buf[j]], mod - 2) % mod;
if (j != mid)
{
C[c[1]] = (LL)C[c[1]] * Pow(A[buf[j]], mod - 2) % mod;
C[root] = (LL)C[root] * Pow(A[buf[j]], mod - 2) % mod;
AR[root] = (LL)AR[root] * Pow(A[buf[j]], j - mid) % mod;
}
else
{
C[c[1]] = (LL)C[c[1]] * ((nxt[j] <= R) ? Pow(A[buf[j]], mod - 2) : 1) % mod;
C[root] = (LL)C[root] * ((nxt[j] <= R) ? Pow(A[buf[j]], mod - 2) : 1) % mod;
AR[root] = (LL)AR[root] * Pow(A[buf[mid]], ((nxt[j]>R) ? R : nxt[j] - 1) - mid + 1) % mod;
}
AL[root] = (LL)AL[root] * Pow(A[buf[j]], mid - bk) % mod;
}
}
ans = (LL)ans*Pow(AL[c[0]], (LL)(R - mid + 1)*buf[mid] % mod_1) % mod;
AR[root] = (LL)AR[root] * Pow(C[c[0]], R - mid + 1) % mod;
if (nxt[mid]>R&&fst[mid]<L) C[root] = (LL)C[root] * A[buf[mid]] % mod;
}
}
}
void init(int n)
{
A[0] = A[n + 1] = 0x3f3f3f3f;
for (int i = 2; i < Sqr; i++)
{
if (used[i])continue;
for (int j = i; j < MAXN; j += i) used[j] = 1;
for (int j = 1; j <= n; j++)
{
A[j] = 0;
int t = buf[j];
while (t%i == 0)
{
A[j]++;
t /= i;
}
}
memset(tmp, 0, sizeof tmp);
memset(tmp2, 0, sizeof tmp2);
stk[0] = 0;
for (int j = 1, top = 0; j <= n; j++)
{
while (A[stk[top]] < A[j])top--;
bfst[j] = fst[j] = stk[top];
stk[++top] = j;
}
stk[0] = n + 1;
for (int j = n, top = 0; j; j--)
{
while (A[stk[top]] <= A[j])top--;
bnxt[j] = nxt[j] = stk[top];
stk[++top] = j;
}
BFS_1(D.root, i);
}
for (int i = 0; i < MAXN; i++)A[i] = 1;
for (int i = Sqr; i < MAXN; i++)
{
if (used[i])continue;
for (int j = i; j < MAXN; j += i)
{
used[j] = 1;
A[j] = i;
}
}
memset(tmp, 0, sizeof tmp);
for (int i = 1; i <= n; i++)
{
fst[i] = tmp[A[buf[i]]];
tmp[A[buf[i]]] = i;
}
for (int i = 0; i < MAXN; i++)tmp[i] = n + 1;
for (int j = n; j; j--)
{
nxt[j] = tmp[A[buf[j]]];
tmp[A[buf[j]]] = j;
}
memset(tmp, 0, sizeof tmp);
memset(tmp2, 0, sizeof tmp2);
memset(used, 0, sizeof used);
AL[0] = AR[0] = C[0] = 1;
BFS_2(D.root);
}
int main()
{
int n;
n = I.read();
for (int i = 1; i <= n; i++)
{
buf[i] = I.read();
D.insert(buf[i]);
}
D.BFS(D.root);
init(n);
for (int i = 2; i < MAXN; i++) ans = (LL)ans*Pow(i, G[i]) % mod;
printf("%d\n", ans);
return 0;
}