您的位置:首页 > 其它

codeforces 594D题解

2015-11-10 19:22 253 查看

D. REQ

time limit per test3 seconds

memory limit per test256 megabytes

input standard input

output standard output

Today on a math lesson the teacher told Vovochka that the Euler function of a positive integer φ(n) is an arithmetic function that counts the positive integers less than or equal to n that are relatively prime to n. The number 1 is coprime to all the positive integers and φ(1) = 1.

Now the teacher gave Vovochka an array of n positive integers a1, a2, …, an and a task to process q queries li ri — to calculate and print modulo 109 + 7. As it is too hard for a second grade school student, you’ve decided to help Vovochka.

Input

The first line of the input contains number n (1 ≤ n ≤ 200 000) — the length of the array given to Vovochka. The second line contains n integers a1, a2, …, an (1 ≤ ai ≤ 106).

The third line contains integer q (1 ≤ q ≤ 200 000) — the number of queries. Next q lines contain the queries, one per line. Each query is defined by the boundaries of the segment li and ri (1 ≤ li ≤ ri ≤ n).

Output

Print q numbers — the value of the Euler function for each query, calculated modulo 109 + 7.

Sample test(s)

input

10

1 2 3 4 5 6 7 8 9 10

7

1 1

3 8

5 6

4 8

8 10

7 9

7 10

output

1

4608

8

1536

192

144

1152

input

7

24 63 13 52 6 10 1

6

3 5

4 7

1 7

2 4

3 6

2 6

output

1248

768

12939264

11232

9984

539136

Note

In the second sample the values are calculated like that:

φ(13·52·6) = φ(4056) = 1248

φ(52·6·10·1) = φ(3120) = 768

φ(24·63·13·52·6·10·1) = φ(61326720) = 12939264

φ(63·13·52) = φ(42588) = 11232

φ(13·52·6·10) = φ(40560) = 9984

φ(63·13·52·6·10) = φ(2555280) = 539136

算法

离线处理每一组询问

列出欧拉函数的公式 观察每一项素因子对最后答案的贡献

用树状数组维护前缀答案

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#define MAXN 200011
#define limit 1000011
int                                 n,a[MAXN],minp[limit],b[limit],v,prime[limit],t[MAXN],m,ans[MAXN];
typedef long long ll;
const ll mod=1e9+7;
using namespace std;
struct Node
{
int l,r,num;
}q[MAXN];
inline bool cmp(Node a,Node b)
{
return a.r<b.r;
}
inline void predeal()
{
int tot=0;
for (int i=2;i<=v;i++)
{
if(!minp[i])prime[tot++]=i,minp[i]=i;
for (int j=0;j<tot;j++)
{
if(prime[j]*i>v)break;
minp[prime[j]*i]=prime[j];
if(i%prime[j]==0)break;
}
}
for (int i=0;i<=n;i++)
t[i]=1;
}
inline int pow(int a,ll b)
{
int r=1,base=a;
while(b)
{
if(b&1)r=(ll)r*base%mod;
base=(ll)base*base%mod;
b>>=1;
}
return r%mod;
}
inline void modify(int x,int z)
{
for (int i=x;i<=n;i+=i&-i)
t[i]=(ll)t[i]*z%mod;
}
inline int query(int x)
{
int temp=1;
for (int i=x;i;i-=i&-i)
temp=(ll)temp*t[i]%mod;
return temp;
}
inline void change(int p)
{
int x=a[p];
while(x!=1)
{
int now=minp[x];
if(b[now])
{
modify(b[now],pow(now-1,mod-2));
modify(b[now],now);
}
b[now]=p;
modify(p,now-1);
x/=now;
}
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
v=*max_element(a+1,a+1+n);
predeal();
scanf("%d",&m);
for (int i=1;i<=m;i++)
{
scanf("%d%d",&q[i].l,&q[i].r);
q[i].num=i;
}
sort(q+1,q+1+m,cmp);
for (int i=1,now=1;i<=m;i++)
{
while(now<=q[i].r)change(now++);
ans[q[i].num]=(ll)query(q[i].r)*pow(query(q[i].l-1),mod-2)%mod;
}
for (int i=1;i<=m;i++)
printf("%d\n",ans[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: