Created
March 20, 2016 18:17
-
-
Save valexey/de70ea611182abcaf44d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Round floating point numbers | |
import std.stdio; | |
import std.algorithm; | |
const int N = 200000, NN = 1 << 18, Q = 200000, MAX = 1000001, MOD = 1000000007; | |
int ri() | |
{ | |
int x; | |
readf(" %s", &x); | |
return x; | |
} | |
struct B | |
{ | |
int l, r, id; | |
}; | |
B b[Q]; | |
int pre[MAX]; | |
int fac[MAX]; | |
int a[N]; | |
int prod[N]; | |
int seg[NN*2]; | |
int ans[Q]; | |
void modify(int l, int r, int x) | |
{ | |
l += NN-1; | |
r += NN-1; | |
for (; l < r; l >>= 1, r >>= 1) { | |
if (l%2 == 0) | |
seg[l] = seg[l] * long(x) % MOD; | |
if (r%2 == 0) | |
r--, seg[r] = seg[r] * long(x) % MOD; | |
} | |
} | |
int query(int i) | |
{ | |
int r = 1; | |
for (i += NN-1; ; ) { | |
r = r * long(seg[i]) % MOD; | |
if (! i) break; | |
i = i-1 >> 1; | |
} | |
return r; | |
} | |
int inv(int x) | |
{ | |
int r = 1; | |
for (; x > 1; x = MOD % x) | |
r = r * long(-MOD/x) % MOD; | |
return (r+MOD)%MOD; | |
} | |
void main() | |
{ | |
/* | |
#define FOR(i, a, b) for (int i = (a); i < (b); i++) | |
#define REP(i, n) for (int i = 0; i < (n); i++) | |
*/ | |
for (int i = 2; i<MAX; i++) | |
if (! fac[i]) | |
for (int j = i; j < MAX; j += i) | |
fac[j] = i; | |
int n = ri(); | |
for (int i = 0; i<n; i++) { | |
a[i] = ri(); | |
prod[i] = (i ? prod[i-1] : 1) * long(a[i]) % MOD; | |
} | |
int q = ri(); | |
for( int i=0; i<q; i++) { | |
b[i].id = i; | |
b[i].l = ri()-1; | |
b[i].r = ri()-1; | |
} | |
sort!("a.r < b.r")(b[0..q]); | |
//fill_n(seg, NN*2, 1); | |
for (int i=0; i<NN*2; i++) | |
seg[i] = 1; | |
int j = 0; | |
for(int i=0; i<n; i++) { | |
for (int x = a[i]; x > 1; ) { | |
int y = fac[x]; | |
while ((x /= y) % y == 0){} | |
modify(pre[y], i+1, long(y-1)*inv(y)%MOD); | |
pre[y] = i+1; | |
} | |
for (; j < q && b[j].r == i; j++) | |
ans[b[j].id] = query(b[j].l) * long(prod[i]) % MOD * (b[j].l ? inv(prod[b[j].l-1]) : 1) % MOD; | |
} | |
for(int i=0; i<q; i++) | |
printf("%d\n", ans[i]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment