显示代码纯文本
#include<cstdio>
#include<ctime>
#include<algorithm>
#include<map>
#define N 100005
#define ll long long
using namespace std;
ll n,m,a[N],cnt,op,l,r,x,y,ans;
struct node{ll v,l;}b[N];
bool operator<(const node &x,const node &y){return x.v<y.v;}
map<ll,ll>mp;
void swap(ll &x,ll &y){ll t=x;x=y;y=t;}
map<ll,ll>::iterator split(ll x)
{
auto it=prev(mp.upper_bound(x));
if(it->first==x)return it;
return mp.insert(it,make_pair(x,it->second));
}
ll fp(ll a,ll n,ll mod)
{
ll ans=1;a%=mod;
while(n)
{
if(n&1)ans=ans*a%mod;
a=a*a%mod;
n>>=1;
}
return ans;
}
int main(){
freopen("kdl.in","r",stdin);freopen("kdl.out","w",stdout);
scanf("%lld%lld",&n,&m);for(ll i=1;i<=n;i++)scanf("%lld",a+i);
for(ll i=1;i<=n;i++)
if(i==1||a[i]^a[i-1])
mp[i]=a[i];
mp[n+1]=0;
while(m--)
{
scanf("%lld%lld%lld%lld",&op,&l,&r,&x);
if(l>r)swap(l,r);
switch(op)
{
case 1:{
split(l);split(r+1);
for(auto it=mp.find(l);it->first<=r;it++)
it->second+=x;
break;
}
case 2:{
split(l);split(r+1);
auto it=mp.find(l);
while(it->first!=r+1)it=mp.erase(it);
mp[l]=x;
break;
}
case 3:{
split(l);split(r+1);cnt=0;
for(auto it=mp.find(l);it->first<=r;)
{
ll len=it->first,v=it->second;it++;len=it->first-len;
b[++cnt]={v,len};
}
sort(b+1,b+cnt+1);
for(ll i=1;;i++)
{
if(b[i].l>=x){printf("%lld\n",b[i].v);break;}
x-=b[i].l;
}
break;
}
case 4:{
scanf("%lld",&y);ans=0;
split(l);split(r+1);
for(auto it=mp.find(l);it->first<=r;)
{
ll len=it->first,v=it->second;it++;len=it->first-len;
ans=(ans+fp(v,x,y)*len)%y;
}
printf("%lld\n",ans);
break;
}
}
}
return 0;
}