- \(1\ l\ r\ x\) :对于 \(i\) 满足 \(l \le i \le r\),将 \(a _ i + x\) 赋值给 \(a _ i\)。
- \(2\ l\ r\ x\) :对于 \(i\) 满足 \(l \le i \le r\),将 \(x\) 赋值给 \(a _ i\)。
- \(3\ l\ r\ x\) :输出范围 \([l, r]\) 中第 \(x\) 小的数字,即在所有满足 \(l \le i \le r\) 的 \(a _ i\) 排序后第 \(x\) 小的数字。保证 \(1 \le x \le r - l + 1\)。
- \(4\ l\ r\ x\ y\) :输出范围 \([l, r]\) 中所有 \(a _ i\) 的 \(x\) 次幂之和模 \(y\),即 \(\left( \sum _ {i = l} ^ r {a _ i} ^ x \right) \bmod y\)。
#include<bits/stdc++.h>
#define int long long
#define ins insert
#define er erase
#define lb lower_bound
#define ub upper_bound
#define be begin
#define sit set<_>::iterator
#define fi first
#define se second
#define pb push_back
using namespace std;
constexpr int maxn=5e5+10,p=1e9+7;
int read()
{
int x=0,f=1;
char ch=getchar();
while (ch<'0' || ch>'9')
{
if (ch == '-') f=-1;
ch=getchar();
}
while (ch>='0' && ch<='9')
{
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
return x*f;
}
int n,m,seed,vm;
int a[maxn];
int rnd()
{
int res=seed;
seed=(seed*7+13)%p;
return res;
}
struct _
{
mutable int l,r,v;
bool operator < (const _ &a) const {return l<a.l;};
};
struct __
{
int v,len;
bool operator < (const __ &a) const {return v<a.v;}
};
set<_> st;
sit split(int x)
{
sit it=st.lb({x,0,0});
if (it!=st.end() && it->l == x) return it;
it--;
if (it->r<x) return st.end();
int r=it->r,v=it->v;
it->r=x-1;
return st.ins({x,r,v}).fi;
}
void add(int l,int r,int v)
{
sit it2=split(r+1),it1=split(l);
for (sit i=it1;i!=it2;i++) i->v+=v;
}
void assign(int l,int r,int v)
{
sit it2=split(r+1),it1=split(l);
st.er(it1,it2);
st.ins({l,r,v});
}
int rnk(int l,int r,int k)
{
sit it2=split(r+1),it1=split(l);
vector<__> v;
for (sit i=it1;i!=it2;i++) v.pb({i->v,i->r-i->l+1});
sort(v.begin(),v.end());
int i;
for (i=0;i<v.size();i++)
{
if (k>v[i].len) k-=v[i].len;
else break;
}
return v[i].v;
}
int power(int x,int y,int mo)
{
int res=1;
x%=mo;
while (y)
{
if (y&1) (res*=x)%=mo;
(x*=x)%=mo;
y>>=1;
}
return res;
}
int calc(int l,int r,int x,int y)
{
sit it2=split(r+1),it1=split(l);
int ans=0;
for (sit i=it1;i!=it2;i++) (ans+=power(i->v,x,y)*(i->r-i->l+1)%y)%=y;
return ans;
}
signed main()
{
n=read(),m=read(),seed=read(),vm=read();
for (int i=1;i<=n;i++)
{
a[i]=(rnd()%vm)+1;
st.ins({i,i,a[i]});
}
for (int i=1;i<=m;i++)
{
int x=0,y=0;
int op=(rnd()%4)+1;
int l=(rnd()%n)+1;
int r=(rnd()%n)+1;
if (l>r) swap(l,r);
if (op == 3) x=(rnd()%(r-l+1))+1;
else x=(rnd()%vm)+1;
if (op == 4) y=(rnd()%vm)+1;
if (op == 1) add(l,r,x);
else if (op == 2) assign(l,r,x);
else if (op == 3) printf("%lld\n",rnk(l,r,x));
else printf("%lld\n",calc(l,r,x,y));
}
return 0;
}