由于是随机数生成,所以可以用map或者set的平衡树维护。
对于各类操作,暴力即可(看了题解,一口老血吐出来)
注意操作2是,删除后合并即可。
注意如果数在某个区间内,直接map tree[A] = B ,即new了该结点,
还有注意upper_bound,和lower_bound返回的指针。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 150005 ;
ll seed , vmax , n , m;
ll rnd(){
ll ret = seed ;
seed = (seed * 7 + 13) % 1000000007 ;
return ret ;
}
ll Power(ll Base, ll Exp, ll Mod)
{
Base %= Mod;
ll res = 1 ;
do
{
if (Exp & 1)
(res *= Base) %= Mod;
(Base *= Base) %= Mod;
}
while (Exp >>= 1);
return res;
}
map<int , ll > tree ;
void print(){
for(auto i = tree.begin() ; i != tree.end() ; i ++ ){
cout << i->second << " " ;
}cout << endl ;
}
void initinit(){
ll temp ;
for(int i = 1 ; i <= n ; i ++ ){
temp = (rnd() % vmax) + 1 ;
tree.insert(tree.end() , make_pair(i , temp)) ;
}
tree.insert(tree.end() , make_pair(n + 1 , 0)) ;
int op , l , r , x , y ;
for(int i = 1 ; i <= m ; i ++ ){
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 ;
///may l and r between other range
auto it_l = -- tree.upper_bound(l) ;
if(it_l->first != l){
tree[l] = it_l->second ;
++ it_l ;
}
auto it_r = tree.lower_bound(r + 1) ;
if(it_r->first != r + 1) {
-- it_r ;
tree[r + 1] = it_r->second ;
++ it_r ;
}
//print() ;
bool flag = 0 ;
switch(op){
static vector<pair<ll , int> > v ;
static ll res ;
case 1:
while(it_l != it_r)
(-- it_r)->second += x ;
break ;
case 2:
while(it_l != it_r)
tree.erase(it_l ++ ) ;
tree[l] = x ;
break ;
case 3:
v.clear() ;
for(int ub ; it_l != it_r ; ){
ub = (it_r --)->first ;
v.push_back(make_pair
(it_r->second, ub - it_r->first)) ;
}
sort(v.begin() , v.end()) ;
for(int i = 0 , cnt = 0 ; ; i ++ ){
if(x <= (cnt += v[i].second)){
printf("%lld\n" , v[i].first) ;
break ;
}
}
break ;
case 4:{
res = 0 ;
for(int ub ; it_l != it_r ; ) {
ub = (it_r --)->first ;
res = (res + (Power(it_r->second, x, y) * (ub - it_r->first)) %y ) % y;
}
printf("%lld\n" , res) ;
break ;
}
}
}
}
int main(){
scanf("%d %d %lld %d" , &n , &m , &seed , &vmax) ;
initinit() ;
return 0 ;
}