首先要知道phi(x^k)=x^k-x^(k-1)=x^(k-1)*(x-1)=x^k*((x-1)/x)
然后用主席树维护区间不同种质数的贡献(每种质数贡献(x-1)/x))就好了
(和HH的项链比较像)
但是卡了一天,一直T......qwq
后面发现是找质因子的时候复杂度过大,因为如果有一个大质数,就会几乎跑满,如果都是大质数就......
然后特判了如果除到质数就break就能A了
/**************************************************************
Problem: 4026
User: syh0313
Language: C++
Result: Accepted
Time:5720 ms
Memory:100504 kb
****************************************************************/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <map>
#include <vector>
#define lch a[n].lc
#define rch a[n].rc
using
namespace
std;
const
int
maxn=50010;
const
int
mo=1000777;
int
n,m,v[maxn],cnt,prime[1000010],st[1000010],root[maxn],topt,lim;
long
long
p[1000010],ans,sum[maxn],ss,in[maxn];
bool
f[1000010];
struct
da{
int
lc,rc;
long
long
sum;}a[maxn*100];
vector<
int
>nt[maxn],pri[maxn];
inline
long
long
po(
long
long
a,
int
b)
{
if
(b==0)
return
1;
if
(b==1)
return
a;
long
long
c=po(a,b/2);
if
(b&1)
return
c*c%mo*a%mo;
else
return
c*c%mo;
}
inline
long
long
inv(
long
long
x){
return
po(x,mo-2);}
inline
void
init()
{
memset
(f,1,
sizeof
f); f[1]=0; st[1]=n+1; sum[0]=1ll; in[0]=1;
register
int
i;
for
(i=2;i<=1000000;i++)
{
st[i]=n+1;
if
(f[i])
{
prime[++cnt]=i;
p[i]=1ll*(i-1)*inv(1ll*i)%mo;
}
for
(
int
j=1;j<=cnt && i*prime[j]<=1000000;j++)
{
f[i*prime[j]]=0;
if
(i%prime[j]==0)
break
;
}
}
}
inline
void
updata(
int
n){a[n].sum=a[lch].sum*a[rch].sum%mo;}
inline
void
build_tree(
int
&n,
int
l,
int
r)
{
n=++topt; a[n].sum=1ll;
if
(l==r) {a[n].sum=1ll;
return
;}
int
mid=(l+r)>>1;
build_tree(lch,l,mid); build_tree(rch,mid+1,r);
}
inline
void
tree_mul(
int
old,
int
&n,
int
l,
int
r,
int
lc,
long
long
k)
{
if
(n<=lim) n=++topt;
if
(l==r)
{
if
(!a[n].sum) a[n].sum=a[old].sum*k%mo;
else
a[n].sum=a[n].sum*k%mo;
return
;
}
int
mid=(l+r)>>1;
if
(lc<=mid)
{
if
(!rch) rch=a[old].rc;
tree_mul(a[old].lc,lch,l,mid,lc,k);
}
else
{
if
(!lch) lch=a[old].lc;
tree_mul(a[old].rc,rch,mid+1,r,lc,k);
}
updata(n);
}
inline
long
long
qury(
int
old,
int
n,
int
L,
int
R,
int
l,
int
r)
{
if
(L==l && R==r) {ss=ss*a[old].sum%mo;
return
a[n].sum;}
int
mid=(L+R)>>1;
if
(r<=mid)
return
qury(a[old].lc,lch,L,mid,l,r);
else
if
(l>=mid+1)
return
qury(a[old].rc,rch,mid+1,R,l,r);
return
qury(a[old].lc,lch,L,mid,l,mid)*qury(a[old].rc,rch,mid+1,R,mid+1,r)%mo;
}
inline
int
read()
{
int
xx=0,ff=1;
char
c=
getchar
();
while
(c<
'0'
|| c>
'9'
) {
if
(c==
'-'
) ff=-1; c=
getchar
();}
while
(c>=
'0'
&& c<=
'9'
) {xx=(xx<<1)+(xx<<3)+c-
'0'
; c=
getchar
();}
return
xx*ff;
}
int
main()
{
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
n=read(); m=read(); init();
register
int
i,j;
for
(i=1;i<=n;i++) v[i]=read(),sum[i]=sum[i-1]*v[i]%mo,in[i]=inv(sum[i]);
for
(i=n;i>=1;i--)
{
int
x=v[i];
for
(j=1;prime[j]<=x;j++)
{
if
(f[x])
{
nt[i].push_back(st[x]);
pri[i].push_back(x);
st[x]=i;
break
;
}
int
num=0;
while
(x%prime[j]==0) {num++; x/=prime[j];}
if
(num)
{
nt[i].push_back(st[prime[j]]);
pri[i].push_back(prime[j]);
st[prime[j]]=i;
}
}
}
build_tree(root[0],1,n+1);
for
(i=1;i<=n;i++)
{
lim=topt;
if
(v[i]==1)
{
root[i]=++topt; a[topt].lc=a[root[i-1]].lc; a[topt].rc=a[root[i-1]].rc;
continue
;
}
for
(
int
j=0;j<nt[i].size();j++)
tree_mul(root[i-1],root[i],1,n+1,nt[i][j],p[pri[i][j]]);
}
while
(m--)
{
int
l,r; l=read(); r=read(); ss=1ll; l^=ans; r^=ans;
ans=sum[r]*qury(root[l-1],root[r],1,n+1,r+1,n+1)%mo*in[l-1]%mo*inv(ss)%mo;
printf
(
"%lld\n"
,ans);
}
return
0;
}