时间限制:C/C++ 3秒,其他语言6秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
珂朵莉给你一个长为n的序列,有m次查询
每次查询给两个数l,r
设s为区间[l,r]内所有数的乘积
求s的约数个数mod 1000000007
输入描述:
第一行两个正整数n,m
第二行一个长为n的序列
之后m行每行两个数l和r
输出描述:
对于每个询问,输出一个整数表示答案
示例1
输入
5 5
64 2 18 9 100
1 5
2 4
2 3
1 4
3 4
输出
165
15
9
45
10
备注:
对于100%的数据,有n , m <= 100000 , a[i] <= 1000000
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 1e3+11;
const int M = 1e6+11;
const int A = 1e6+11;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
int block; // 分块
bool su[N];int prm[N],sz;
void init(){ //素筛
su[0]=su[1]=1;
for(int i=2;i<=N;i++){
if(!su[i]) prm[++sz]=i;
for(int j=1;j<=sz;j++){
int t=i*prm[j];
if(t>N) break;
su[t]=1;
if(i%prm[j]==0) break;
}
}
// printf("sz==%d\n",sz);
}
struct Query{
int l,r,id;
bool operator <(const Query &b) const {
if( (l-1)/block != (b.l-1)/block )
return ((l-1)/block )< ((b.l-1)/block) ;
return r<b.r;
}
}Q[M];
int sum[M][200]; int fac[M]; int Inv[M+11];
int Cnt[A]; LL Ans[M]; LL ans;
void Add(int x){
int y=fac[x];
if(y==1)return; // 质因子都在1e3之内的,已经算过了,跳过
ans=ans*Inv[Cnt[y]+1]%mod;
Cnt[y]++;
ans=ans*(Cnt[y]+1)%mod;
}
void Del(int x){
int y=fac[x];
if(y==1) return;
ans=ans*Inv[Cnt[y]+1]%mod;
Cnt[y]--;
ans=ans*(Cnt[y]+1)%mod;
}
void solve(int m){
sort(Q+1,Q+1+m);
memset(Cnt,0,sizeof(Cnt));
int L=1,R=0; ans=1;
for(int i=1;i<=m;i++){
int id=Q[i].id;
while(R<Q[i].r) Add(++R);
while(L>Q[i].l) Add(--L);
while(R>Q[i].r) Del(R--);
while(L<Q[i].l) Del(L++);
Ans[id]*=ans%mod;
Ans[id]%=mod;
}
for(int j=1;j<=m;j++) printf("%lld\n",Ans[j]);
}
int main(){
init();
int n,m; scanf("%d%d",&n,&m); block=(int)sqrt(n*1.0);
Inv[1]=1; for(int i=2;i<=n+11;i++) Inv[i]=1LL*(mod-mod/i)*Inv[mod%i]%mod ; // 逆元筛
for(int i=1;i<=n;i++){
int t; scanf("%d",&t);
for(int j=1;j<=sz;j++){
sum[i][j]+=sum[i-1][j];
while((t%prm[j])==0) { sum[i][j]++; t/=prm[j]; }
}
fac[i]=t; // 获得大于1e3的 质因子
}
for(int i=1;i<=m;i++){ // 可以先处理出来 质因子小于1e3的种类数目
scanf("%d%d",&Q[i].l,&Q[i].r); Q[i].id=i;
LL res=1;
for(int j=1;j<=sz;j++)
res=res*(sum[Q[i].r][j]-sum[Q[i].l-1][j]+1)%mod;
Ans[i]=res;
}
solve(m); //莫队处理 质因子大于1e3的情况数目
return 0;
}