When you draw a persimmon, you will know that it is the formula for finding all the prime factors in the product multiplication interval (MA)/P (that is, the Euler's formula)
It seems that Mo team is very reliable, but time O (nsqrt (n) logn) is not porcelain
Or offline. determine the right endpoint ~ We insert the prime factor in the I range into the last position in the tree array, and scan the inverse element + find the prime factor O (nlog ^ 2n)
Note that we cannot use Trial Division when calculating the quality factor.
#include<cstdio>#include<iostream>#include<cstring>#include<cstdlib>#include<algorithm>#include<cmath>using namespace std;typedef long long LL;const LL mod=1e9+7;int quick_pow(int A,int p){ int ret=1; while(p!=0) { if(p%2==1)ret=(LL)ret*A%mod; A=(LL)A*A%mod;p/=2; } return ret;}int inv(int A){return quick_pow(A,mod-2);}int pr,prime[1100000],pm[1100000];bool v[1100000];void get_prime(){ pr=0; for(int i=2;i<=1001000;i++) { if(v[i]==false)prime[++pr]=i,pm[i]=i; for(int j=1;j<=pr&&i*prime[j]<=1001000;j++) { v[i*prime[j]]=true; pm[i*prime[j]]=min(pm[i],prime[j]); if(i%prime[j]==0)break; } }}int n;LL s[210000];int lowbit(int x){return x&-x;}void change(int x,LL k){ while(x<=n) { s[x]=s[x]*k%mod; x+=lowbit(x); }}LL getsum(int x){ LL ret=1; while(x>0) { ret=ret*s[x]%mod; x-=lowbit(x); } return ret;}int a[210000];LL sm[210000];struct query{int l,r,id;}q[210000];int as[210000];bool cmp(query q1,query q2){return q1.r<q2.r;}int last[1100000];int main(){ get_prime(); scanf("%d",&n); sm[0]=1; for(int i=1;i<=n;i++) scanf("%d",&a[i]), sm[i]=sm[i-1]*a[i]%mod; int Q; scanf("%d",&Q); for(int i=1;i<=Q;i++) scanf("%d%d",&q[i].l,&q[i].r), q[i].id=i; sort(q+1,q+Q+1,cmp); int j=1; memset(last,0,sizeof(last)); for(int i=1;i<=n;i++)s[i]=1; for(int i=1;i<=n;i++) { int d=a[i]; while(d>1) { int p=pm[d];LL c=(LL)(p-1)*inv(p)%mod; if(last[p]>0)change(last[p],inv(c)); last[p]=i; change(last[p],c); while(d%p==0)d/=p; } while(j<=Q&&q[j].r==i) { as[q[j].id]=sm[q[j].r]*inv(sm[q[j].l-1])%mod*getsum(q[j].r)%mod*inv(getsum(q[j].l-1))%mod; j++; } } for(int i=1;i<=Q;i++)printf("%d\n",as[i]); return 0;}
51nod 1642 interval Euler's Function & codeforce594d req