社区讨论

ODT/珂朵莉树求助,样例过不了,每次都会少加一个数字

CF896CWillem, Chtholly and Seniorious参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lo7veok3
此快照首次捕获于
2023/10/27 08:23
2 年前
此快照最后确认于
2023/10/27 08:23
2 年前
查看原帖
CPP
#include <bits/stdc++.h>
using namespace std;
typedef long long int64;
const int mp = 1000000007;
int64 qpow(int64 base, int64 index, int mod) {
	int64 res = 1; base %= mod;
	while (index) {
		if (index & 1) { res *= base; res %= mod; };
		base = (base * base) % mod; index >>= 1;
	}
	return res;
}
struct ctholly {
	struct node {
		int l, r;
		mutable int64 v;
		node(int l, int r = 0, int64 v = 0) : l(l), r(r), v(v) {};
		bool operator <(const node &rhs) const {
			return l < rhs.l;
		}
	};
	set<node> s;
	set<node>::iterator split(int p) {
		set<node>::iterator it = s.lower_bound(node(p));
		if (it != s.end() && it -> l == p) return it;
		it --;
		if (it -> r < p) return s.end();
		int l = it -> l, r = it -> r; int64 v = it -> v;
		s.erase(it), s.insert(node(1, p - 1, v));
		return s.insert(node(p, r, v)).first;
	}
	void init_val(int len, int64 v) {
		s.insert(node(1, len, v));
	}
	void init_array(int len, const int64 a[]) {
		for (int i = 1; i <= len; i ++) {
			s.insert(node(i, i, a[i]));
		}
	}
	void assign(int l, int r, int64 v) {
		set<node>::iterator itr = split(r + 1), itl = split(l);
		s.erase(itl, itr), s.insert(node(l, r, v));
	}
	void add(int l, int r, int64 v) {
		set<node>::iterator itr = split(r + 1), itl = split(l);
		for (set<node>::iterator it = itl; it != itr; it ++)
			it -> v += v;
	}
	int64 sum(int l, int r) {
		set<node>::iterator itr = split(r + 1), itl = split(l);
		int64 ret = 0;
		for	(set<node>::iterator it = itl; it != itr; it ++)
			ret += (it -> r - it -> l + 1) * it -> v;
		return ret;
	}	
	int64 rank(int l, int r, int k) {
		set<node>::iterator itr = split(r + 1), itl = split(l);
		vector<pair<int64, int64> > vp;
		for (set<node>::iterator it = itl; it != itr; it ++)
			vp.push_back(make_pair(it -> v, it -> r - it -> l + 1));
		sort(vp.begin(), vp.end());
		int64 ret;
		for (int i = 0; i < vp.size() && k > 0; i ++) {
			k -= vp[i].second; ret = vp[i].first;
		}
		return ret;
	}
	int64 pow_sum(int l, int r, int ex, int y) {
		set<node>::iterator itr = split(r + 1), itl = split(l);
		int64 ret = 0;
		for (set<node>::iterator it = itl; it != itr; it ++) {
			ret += ((it -> r - it -> l + 1) * qpow(it -> v, ex, y)) % y;
			ret %= y;
		}
		return ret;
	}
};
ctholly c;
int64 a[100010];
int n, m;
int64 seed, vmax;
int64 rnd() {
	int64 ret = seed;
	seed = (seed * 7 + 13) % mp;
	return ret;
}
int main() {
	cin >> n >> m >> seed >> vmax;
	for (int i = 1; i <= n; i ++) {
		a[i] = (rnd() % vmax) + 1;
	}
	c.init_array(n, a);
	while (m --) {
		int64 op = (rnd() % 4) + 1;
		int64 l = (rnd() % n) + 1;
		int64 r = (rnd() % n) + 1;
		if (l > r) swap(l, r);
		int64 x, y;
		if (op == 3) x = (rnd() % (r - l + 1)) + 1;
		else x = (rnd() % vmax) + 1;
		if (op == 4) y = (rnd() % vmax) + 1;
		if (op == 1) c.add(l, r, x);
		if (op == 2) c.assign(l, r, x);
		if (op == 3) cout << c.rank(l, r, x) << '\n';
		if (op == 4) cout << c.pow_sum(l, r, x, y) << '\n';
	}
	return 0;
} 

代码中sum和pow_sum函数似乎在求和时都会少加一个数字,求助。

回复

0 条回复,欢迎继续交流。

正在加载回复...