分析:

区间修改和单点查询可以用 实现,更简单。
欧拉定理拓展(欧拉降幂)
图片说明
经过多次的 ,终于发现了问题的所在。关键在于当指数 和模数 的关系不同时,对其的操作也不同。
即代码如下:

ll Mod(ll x,ll y)//欧拉定理的判断条件
{
    return x>=y?(x%y+y):x;
}

此外,本题为一个递归的过程,当借助快速幂来求一个数的幂,考虑到其可能作为另一个数的指数,所以对其取模时,同样不能乱取,也要按照上述的标准。
考虑到了这些,问题就很简单了。

代码:

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
const int N=5e5+5;
const int maxn=2e7+5;
typedef long long ll;
ll bit[N];
int n;
vector<int>prime;
bool vis[maxn];
int phi[maxn];
void read(int &x)
{
    x=0;
    int f=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        x=(x<<3)+(x<<1)+ch-'0';
        ch=getchar();
    }
    x*=f;
}
void init()
{
    phi[1]=1;
    for(int i=2;i<maxn;i++)
    {
        if(!vis[i])
        {
            prime.pb(i);
            phi[i]=i-1;
        }
        for(int j=0;j<prime.size()&&i*prime[j]<maxn;j++)
        {
            vis[i*prime[j]]=1;
            if(i%prime[j]==0)
            {
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
            else
                phi[i*prime[j]]=phi[i]*phi[prime[j]];
        }
    }
}
void update(int p,ll val)
{
    while(p<=n)
    {
        bit[p]+=val;
        p+=(p&-p);
    }
}
ll query(int p)
{
    ll res=0;
    while(p>0)
    {
        res+=bit[p];
        p-=(p&-p);
    }
    return res;
}
void range_update(int l,int r,ll val)
{
    update(l,val);
    update(r+1,-val);
}
ll Mod(ll x,ll y)//欧拉定理的判断条件
{
    return x>=y?(x%y+y):x;
}
ll power(ll a,ll b,ll p)
{
    ll res=1;
    a=Mod(a,p);
    while(b)
    {
        if(b&1)
            res=Mod(res*a,p);
        a=Mod(a*a,p);
        b>>=1;
    }
    return res;
}
ll dfs(int v,int p,int r)
{
    ll tn=query(v);
    if(v==r||p==1)
        return Mod(tn,1LL*p);
    ll res=dfs(v+1,phi[p],r);//保留原始值
    return power(tn,res,1LL*p);
}
int main()
{
    init();
    int m,a,op,l,r,x,p;
    read(n),read(m);
    for(int i=1;i<=n;i++)
    {
        read(a);
        range_update(i,i,a);
    }
    while(m--)
    {
        read(op),read(l),read(r);
        if(op==1)
        {
            read(x);
            range_update(l,r,1LL*x);
        }
        else
        {
            read(p);
            printf("%lld\n",dfs(l,p,r)%p);
        }
    }
    return 0;
}