D. Power Tower

time limit per test:4.5 seconds

memory limit per test:256 megabytes

input:standard input

output:standard output

Priests of the Quetzalcoatl cult want to build a tower to represent a power of their god. Tower is usually made of power-charged rocks. It is built with the help of rare magic by levitating the current top of tower and adding rocks at its bottom. If top, which is built from k - 1 rocks, possesses power p and we want to add the rock charged with power wk then value of power of a new tower will be {wk}p.

Rocks are added from the last to the first. That is for sequence w1, ..., wm value of power will be

CodeForces 906D Power Tower(欧拉降幂定理)_CodeForces

After tower is built, its power may be extremely large. But still priests want to get some information about it, namely they want to know a number called cumulative power which is the true value of power taken modulo m. Priests have n rocks numbered from 1 to n. They ask you to calculate which value of cumulative power will the tower possess if they will build it from rocks numbered l, l + 1, ..., r.

Input

First line of input contains two integers n (1 ≤ n ≤ 105) and m (1 ≤ m ≤ 109).

Second line of input contains n integers wk (1 ≤ wk ≤ 109) which is the power of rocks that priests have.

Third line of input contains single integer q (1 ≤ q ≤ 105) which is amount of queries from priests to you.

kth of next q lines contains two integers lk and rk (1 ≤ lk ≤ rk ≤ n).

Output

Output q integers. k-th of them must be the amount of cumulative power the tower will have if is built from rocks lk, lk + 1, ..., rk.

Example

Input

6 1000000000
1 2 2 3 3 3
8
1 1
1 6
2 2
2 3
2 4
4 4
4 5
4 6

Output

1
1
2
4
256
3
27
597484987

Note

3^27 = 7625597484987

 

 

        一道定理题。

        大致题意:有N个数字,然后给你q个区间,要你求每一个区间中所有的数字从左到右一次垒起来的次方的幂对m取模之后的数字是多少。

        根据欧拉降幂公式:

CodeForces 906D Power Tower(欧拉降幂定理)_快速幂_02

,这个式子当且仅当x>φ(m)时满足。如此一来,这个次方的过程可以变成一个递归的过程,每一个数字的指数等于后一个数字到右端点的幂。可以预见,这个迭代,相当于也是φ函数的一个迭代,显然当φ函数值等于1的时候已经可以不用往后递归了,而可以证明φ函数嵌套多次,知道数值等于1,它的次数不会超过log(N)。于是总的复杂度就是O(logNlogN),即递归次数和快速幂次数。然后具体实现上,注意式子满足的条件,我们要始终保证返回值如果大于φ,那么对它取模并加上φ,否则不做处理。为了保证不出错,在快速幂的中间阶段取模时就要用这种方式取模,然后在求phi的时候进行记忆化求取,不然会超时。具体见代码:

#include<bits/stdc++.h>
#define Mod(a,b) a<b?a:a%b+b //重定义取模,按照欧拉定理的条件
#define LL long long
#define N 100010
using namespace std;

LL n,q,mod,a[N];
map<LL,LL> mp;

LL qpow(LL x,LL n,LL mod)
{
LL res=1;
while(n)
{
if (n&1) res=Mod(res*x,mod),n--;
x=Mod(x*x,mod); n>>=1;
}
return res;
}

LL phi(LL k)
{
LL i,s=k,x=k;
if (mp.count(k)) return mp[x]; //记忆化存储
for(i = 2;i * i <= k; i++)
{
if(k % i == 0) s = s / i * (i - 1);
while(k % i == 0) k /= i;
}
if(k > 1) s = s / k * (k - 1);
mp[x]=s; return s;
}

LL solve(LL l,LL r,LL mod)
{
if (l==r||mod==1) return Mod(a[l],mod); //如果到右端点或者φ值等于1,那么直接返回当前数字
return qpow(a[l],solve(l+1,r,phi(mod)),mod); //否则指数为[l+1,r]区间的结果
}

int main()
{
scanf("%lld%lld",&n,&mod);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
scanf("%lld",&q);
while(q--)
{
int L,R;
scanf("%d%d",&L,&R);
printf("%lld\n",solve(L,R,mod)%mod); //对mod取模,因为qpow内部是用Mod(a,b)取模
}
return 0;
}

觉得博主写的好的话,打赏一下吧,互利互惠……