经过测试,应该是操作 3 经常不输出答案。
代码:
#include <iostream>
#include <cctype>
#include <set>
#include <algorithm>
#define update() seed = (seed * 7 + 13) % mod;
#define set_it(x) set<x>::iterator
using namespace std;
typedef long long ll;
ll read()
{
ll x = 0, f = 1;
char ch = getchar();
while(!isdigit(ch))
{
if(ch == '-') f = -1;
ch = getchar();
}
while(isdigit(ch))
x = x * 10 + ch - '0',
ch = getchar();
return x * f;
}
const ll mod = 1e9 + 7;
ll n, m;
ll seed, vmax;
/*------------------------------*/
/*
def rnd():
ret = seed
seed = (seed * 7 + 13) mod 1000000007
return ret
for i = 1 to n:
a[i] = (rnd() mod vmax) + 1
for i = 1 to m:
op = (rnd() mod 4) + 1
l = (rnd() mod n) + 1
r = (rnd() mod n) + 1
if (l > r):
swap(l, r)
if (op == 3):
x = (rnd() mod (r - l + 1)) + 1
else:
x = (rnd() mod vmax) + 1
if (op == 4):
y = (rnd() mod vmax) + 1
*/
const int MAXN = 1e5 + 5, MAXM = 1e5 + 5;
ll a[MAXN], op[MAXM], l[MAXM], r[MAXM], x[MAXM], y[MAXM];
ll rnd()
{
ll res = seed;
update();
return res;
}
void make_data()
{
for(int i = 1; i <= n; i++)
a[i] = rnd() % vmax + 1;
for(int i = 1; i <= m; i++)
{
op[i] = rnd() % 4 + 1;
l[i] = rnd() % n + 1;
r[i] = rnd() % n + 1;
if(l[i] > r[i]) swap(l[i], r[i]);
if(op[i] == 3) x[i] = rnd() % (r - l + 1) + 1;
else x[i] = rnd() % vmax + 1;
if(op[i] == 4) y[i] = rnd() % vmax + 1;
}
return ;
}
/*------------------------------*/
struct node
{
ll l, r;
mutable ll v;
node(ll L, ll R = -1, ll V = 0):
l(L), r(R), v(V) {}
bool operator<(const node& b) const
{
return l < b.l;
}
};
struct stru
{
ll v, s;
} q[MAXN];
set<node> s;
set_it(node) split(ll pos)
{
set_it(node) it = s.lower_bound(node(pos));
if(it != s.end() && it -> l == pos) return it;
--it;
ll l = it -> l, r = it -> r;
ll v = it -> v;
s.erase(it);
s.insert(node(l, pos - 1, v));
return s.insert(node(pos, r, v)).first;
}
void add(ll l, ll r, ll x)
{
set_it(node) itr = split(r + 1), itl = split(l);
for(set_it(node) it = itl; it != itr; it++)
it -> v += x;
return ;
}
void assign(ll l, ll r, ll x)
{
set_it(node) itr = split(r + 1), itl = split(l);
s.erase(itl, itr), s.insert(node(l, r, x));
return ;
}
bool cmp(stru x, stru y)
{
return x.v < y.v;
}
void find(ll l, ll r, ll x)
{
ll cnt = 0;
set_it(node) itr = split(r + 1), itl = split(l);
for(set_it(node) it = itl; it != itr; it++)
q[++cnt] = (stru){it -> v, it -> r - it -> l + 1};
sort(q + 1, q + cnt + 1, cmp);
cout << "x: " << x << endl;
for(int i = 1; i <= cnt; i++)
cout << i << ": " << q[i].v << ' ' << q[i].s << endl;
for(ll i = 1; i <= cnt; i++)
{
if(x <= q[i].s)
{
printf("%lld\n", q[i].v);
break;
}
else x -= q[i].s;
}
return ;
}
ll pow(ll a, ll x, ll p)
{
ll res = 1;
a %= p;
while(x > 0)
{
if(x & 1) res = (res * a) % p;
a = (a * a) % p, x >>= 1;
}
return res;
}
void sum(ll l, ll r, ll x, ll y)
{
set_it(node) itr = split(r + 1), itl = split(l);
ll ans = 0;
for(set_it(node) it = itl; it != itr; it++)
ans = (ans + pow(it -> v % y, x, y) * (it -> r - it -> l + 1) % y) % y;
printf("%d\n", ans);
return ;
}
int main(int argc, char** argv)
{
n = read(), m = read();
seed = read(), vmax = read();
make_data();
for(int i = 1; i <= n; i++)
s.insert(node(i, i, a[i]));
// for(int i = 1; i <= m; i++)
// {
// cout << "=====" << endl;
// cout << i << ": " << endl;
// cout << op[i] << ' ' << l[i] << ' ' << r[i] << endl;
// cout << x[i] << ' ' << y[i] << endl;
// }
for(int i = 1; i <= m; i++)
{
if(op[i] == 1) add(l[i], r[i], x[i]);
if(op[i] == 2) assign(l[i], r[i], x[i]);
if(op[i] == 3) find(l[i], r[i], x[i]);
if(op[i] == 4) sum(l[i], r[i], x[i], y[i]);
}
return 0;
}
感谢