暴力美
忘了就看
#include<bits/stdc++.h>
#define int long long
#define F(i,i0,n) for(int i=i0;i<=n;i++)
using namespace std;
inline int rd(){
int f=0,x=0;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
return f?-x:x;
}
const int N=2e5+5,mod=1e9+7;
struct Node_t{
int l,r;
mutable int v;//突破const的限制使 & 出来后更方便
Node_t(const int &il,const int &ir=0,const int &iv=0):l(il),r(ir),v(iv){}
bool operator<(const Node_t &o)const{return l<o.l;}
};
set<Node_t>s;
int n,m,seed,vmax,a[N];
auto spilt(int pos){
auto it=s.lower_bound(Node_t(pos));
if(it!=s.end()&&it->l==pos)return it;//正好有我所需要的区间
it--;//取上一个
if(it->r<pos)return s.end();//说明找不到
int l=it->l,r=it->r,v=it->v;
s.erase(it);
s.insert(Node_t(l,pos-1,v));
//insert函数返回pair,其中的first是新插入结点的迭代器
return s.insert(Node_t(pos,r,v)).first;
}
void assign(int l,int r,int x){
auto itr=spilt(r+1),itl=spilt(l);
s.erase(itl,itr);
s.insert(Node_t(l,r,x));
}
void add(int l,int r,int x){
auto itr=spilt(r+1),itl=spilt(l);
for(auto it=itl;it!=itr;++it){
it->v+=x;
}
}
struct Rank{
int num,cnt;
};
int kth(int l,int r,int x){
auto itr=spilt(r+1),itl=spilt(l);
vector<Rank>v;
for(auto it=itl;it!=itr;++it)
v.push_back({it->v,it->r - it->l+1});
sort(v.begin(),v.end(),[](const Rank &x1,const Rank &x2){return x1.num<x2.num;});
int i;
for(i=0;i<v.size();++i){
if(v[i].cnt<x)x-=v[i].cnt;
else break;
}
return v[i].num;
}
int Pow(int a,int b,int mod){
int ans=1;
a%=mod;
while(b){
if(b&1)ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
int cal(int l,int r,int x,int y){
auto itr=spilt(r+1),itl=spilt(l);
int ans=0;
for(auto it=itl;it!=itr;++it)
ans=(ans+Pow(it->v,x,y)*(it->r - it->l+1)%y)%y;
return ans;
}
int rnd(){
int ret = seed;
seed = (seed * 7 + 13) %mod;
return ret;
}
signed main(){
n=rd(),m=rd(),seed=rd(),vmax=rd();
for (int i = 1; i <= n; ++i) {
a[i] = (rnd() % vmax) + 1;
s.insert(Node_t(i, i, a[i]));
}
for (int i = 1; i <= m; ++i) {
int op, l, r, x, y;
op = (rnd() % 4) + 1;
l = (rnd() % n) + 1;
r = (rnd() % n) + 1;
if (l > r) swap(l, r);
if (op == 3) {
x = (rnd() % (r - l + 1)) + 1;
} else {
x = (rnd() % vmax) + 1;
}
if (op == 4) {
y = (rnd() % vmax) + 1;
}
if (op == 1) add(l, r, x);
else if (op == 2) assign(l, r, x);
else if (op == 3) cout << kth(l, r, x) << endl;
else cout << cal(l, r, x, y) << endl;
}
return 0;
}