刚学 ODDDDDT
查看原帖
刚学 ODDDDDT
224978
optimize_2楼主2021/4/28 18:11

不过样例..

#include<bits/stdc++.h>
#define iter set<node>::iterator
typedef long long ll;
const int mod = 1e9 + 7;
using namespace std;

struct node {
	int l, r;
	mutable ll v;
	node(int l2, int r2 = -1, ll v2 = 0) {
		l = l2;
		r = r2;
		v = v2;
	}
	bool operator < (const node& b) const {
		return l < b.l;
	}
};
set<node> s;

ll qpow(ll a, ll b, ll mod) {
	ll res = 1,
	   ans = a % mod;
	while (b) {
		if (b&1) res = res * ans % mod;
		ans = ans * ans % mod;
		b >>= 1;
	}
	return res;
}

iter split(int pos) {
	iter it = s.lower_bound(node(pos));
	if (it != s.end() && it -> l == pos) return it;
	it--;
	int 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 assign(int l, int r, ll val = 0 ) {
	iter itl = split(l),
		 itr = split(r + 1);
	s.erase(itl, itr);
	s.insert(node(l, r, val));
}

void add(int l, int r, ll val) {
	iter itl = split(l),
		 itr = split(r + 1);
	for(iter it = itl; it != itr; it++) it -> v += val;
}

ll kth(int l, int r, int k) {
	vector< pair<ll, int> > vp;
	vp.clear();
	iter itl = split(l),
		 itr = split(r + 1);
	for(iter it = itl; it != itr; it++)
		vp.push_back(pair<ll, int>(itl -> v, it -> r - it -> l + 1));
	sort(vp.begin(), vp.end());
	for(vector< pair<ll, int> > :: iterator it = vp.begin(); it != vp.end(); it++) {
		k -= it -> second;
		if(k <= 0) return it -> first;
	}
	return -1ll;
}

ll sum(int l, int r, ll val, int mod) {
	ll ret = 0;
	iter itl = split(l),
		 itr = split(r + 1);
	for(iter it = itl; it != itr; it++) ret = (ret + (ll)(itl -> r - itl -> l + 1) * qpow(itl -> v, ll(val), ll(mod))) % mod;
	return ret;
}

int n, m, vmax;
ll seed, a[100010];

ll rnd() {
	ll ret = seed;
	seed = (seed * 7 + 13) % mod;
	return ret;
}

int main() {
	cin >> n >> m >> seed >> vmax;
	for (int i = 1; i <= n; i++) {
		a[i] = rnd() % vmax + 1;
		s.insert(node(i, i, a[i]));
	}
	s.insert(node(n+1, n+1, 0));
	for (int i = 1; i <= m; i++)
	{
		int op = rnd() % 4 + 1,
			l = rnd() % n + 1,
			r = rnd() % n + 1;
		//cout<<op<<" "<<l<<" "<<r<<endl;
		ll x, y;
		if (l > r) swap(l,r);
		if (op == 3) x = int(rnd() % (r-l+1)) + 1;
		else x = int(rnd() % vmax) +1;
		if (op == 4) y = int(rnd() % vmax) + 1;
		if (op == 1) add(l, r, ll(x));
		else if (op == 2) assign(l, r, ll(x));
		else if (op == 3) cout << kth(l, r, x) << endl;
		else cout << sum(l, r, x, y) << endl;
	}
}
2021/4/28 18:11
加载中...