为什么都RE了?
//由模数皆为小数
//且平方的性质没有更好的处理方法
//找循环节(找规律)
#include<bits/stdc++.h>
#define ll long long
#define R register int
using namespace std;
const int maxn=100010;
ll n,m,p,a,b,opt,LL,RR,ans,c[maxn]={0},vis[maxn]={0},no[maxn]={0};
struct xx
{ ll l,r,now,len,s[61],tag,lz;//对每个结点建循环节的桶
}t[5*maxn];
queue <ll> sea;
void read(ll &x)
{ x=0;
ll w=1;
char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') w=-1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-48;ch=getchar();}
x*=w;
}
void init(ll x)
{ t[x].tag=1;
ll y=t[x].s[0];
for(R i=1;i<=60;++i)
{ y=y*y%p;
if(y==t[x].s[0])
{ t[x].len=i;
break;
}
t[x].s[i]=y;
}
}
void update(ll x)
{ t[x].tag=t[x<<1].tag&t[x<<1|1].tag;
ll lw=t[x<<1].now,rw=t[x<<1|1].now;
if(!t[x].tag)
t[x].s[0]=t[x<<1].s[lw]+t[x<<1|1].s[rw];
if(!t[x].tag||t[x].len)
return;
t[x].s[0]=(t[x<<1].s[lw]+t[x<<1|1].s[rw])%p;
init(x);
}
void build(ll x,ll y,ll z)
{ t[z].l=x;
t[z].r=y;
t[z].tag=0;
t[z].lz=0;
t[z].now=0;
t[z].len=0;
if(x==y)
{ t[z].s[0]=c[x];
if(!no[c[x]])
init(z);
return;
}
ll mid=(x+y)>>1;
build(x,mid,z<<1);
build(mid+1,y,z<<1|1);
update(z);
}
void pushdown(ll x)
{ if(!t[x].lz)
return;
t[x<<1].lz+=t[x].lz;
t[x<<1|1].lz+=t[x].lz;
t[x<<1].now=(t[x<<1].now+t[x].lz)%t[x<<1].len;
t[x<<1|1].now=(t[x<<1|1].now+t[x].lz)%t[x<<1|1].len;
t[x].lz=0;
}
void change(ll x,ll y,ll z)
{ if(t[z].l>=x&&t[z].r<=y)
{ if(t[z].tag)
{ t[z].now=(t[z].now+1)%t[z].len;
t[z].lz++;
return;
}
if(t[z].l==t[z].r)
{ t[z].s[0]=t[z].s[0]*t[z].s[0]%p;
if(!no[t[z].s[0]])
init(z);
return;
}
}
pushdown(z);
//能打上lazy的点tag一定为1
ll mid=(t[z].l+t[z].r)>>1;
if(mid>=x)
change(x,y,z<<1);
if(mid<y)
change(x,y,z<<1|1);
update(z);
}
ll query(ll x,ll y,ll z)
{ if(t[z].l>=x&&t[z].r<=y)
{ ll nw=t[z].now;
return t[z].s[nw];
}
pushdown(z);
ll mid=(t[z].l+t[z].r)>>1,ret=0;
if(mid>=x)
ret=query(x,y,z<<1);
if(mid<y)
ret+=query(x,y,z<<1|1);
return ret;
}
int main()
{ read(n);
read(m);
read(p);
for(R i=0;i<p;++i)
vis[i*i%p]++;//记录入度
for(R i=0;i<p;++i)
if(!vis[i])
sea.push(i);
while(!sea.empty())
{ a=sea.front();
sea.pop();
no[a]=1;
b=a*a%p;
if(--vis[b]==0)
sea.push(b);
}//拓扑排除不在环上的
for(R i=1;i<=n;++i)
read(c[i]);
build(1,n,1);
for(R i=1;i<=m;++i)
{ read(opt);
read(LL);
read(RR);
if(opt==1)
change(LL,RR,1);
else
{ ans=query(LL,RR,1);
printf("%lld\n",ans);
}
}
return 0;
}