#4WA求救
查看原帖
#4WA求救
463071
HOMODELUNA楼主2021/2/14 02:05
//#4测试点WA,第175个数字,要求10368000,结果0
#include<iostream>
#include<set>
#include<functional>
#include<vector>
#include<algorithm>
#include<numeric>
using namespace std;
using LL = long long;
LL n, m, seed, vmax;



template<typename T>
class Chtholly{
public:
	struct node { LL l, r;mutable T v;bool operator<(const node& bb)const { return l < bb.l; }
		node(LL il,LL ir,T iv):l(il),r(ir),v(iv){}
	};
	set<node>tree;
   using IT = decltype(tree.begin());
   
	//把区间[l,r]切分为[l,pos-1]和[pos,r]
	//返回以pos开头的那个节点的迭代器
	auto split(LL pos){
		auto it = tree.lower_bound(node(pos, 0, T()));
		if (it == tree.end()) { return it; }
		if (it->l == pos) { return it; }
		--it;
		LL tl = it->l, tr = it->r;
		T tv = it->v;
		tree.erase(it);
		tree.insert(node(tl, pos - 1, tv));
		return tree.insert(node(pos, tr, tv)).first;
	}
    
	//合并整个区间
	void unite() {
		LL tl, tr; T tv; auto tofin = tree.end(), temp = tofin; tofin--;
		for (auto it = tree.begin();it != tofin;) {
			temp = it; temp++;
			if (it->v == temp->v) {
				tl = it->l; tr = temp->r; tv = it->v;
				temp = tree.erase(temp);
				it=tree.erase(it);
				tree.insert(node(tl, tr, tv));
			}
			else { ++it; }
		}
	}
    
	//区间赋值
	inline void assign(LL il, LL ir, T iv) {
		auto fin = split(ir+1), init = split(il);
		tree.erase(init, fin);
		tree.insert(node(il, ir, iv));
	}
    
	//对某个区间进行变换
	inline void cast(LL il, LL ir, function<void(T&)> func) {
		auto fin = split(ir + 1),it = split(il);
		for (;it != fin;++it) { func(it->v); }
	}
    //输入数据
	inline void insert(LL il, LL ir, T iv) { tree.insert(node(il, ir, iv)); }
    //查错用函数,打印整个树
	void print() {
		for (node i : tree) {
			cout << i.l << "-" << i.v <<"-" << i.r << "\t";
		}
		cout << '\n';
	}
    //在切割之后弥合断点
	inline void repair(decltype(tree.begin()) it) {
		auto temp = it; --temp;
		if (it!=tree.end()&&it!=tree.begin()&&it->v == temp->v) {
			node to_insert(temp->l, it->r, it->v);
			tree.erase(it);
			tree.erase(temp);
			tree.insert(to_insert);
		}
	}
	T operator[](int pos) {
		auto  it=tree.lower_bound(node(pos, 0, T()));
		if (pos < it->l) { --it; }
		return it->v;
	}
};


//生成随机数
inline LL rnd() {
	LL ret = seed;
	seed = (seed * 7 + 13) % 1000000007;
	return ret;
}

//找到第K个数
LL kth(Chtholly<LL>& ch, LL il, LL ir, LL k) {
	vector<pair<LL,LL> >te;
	auto fin = ch.split(ir + 1),init= ch.split(il);
	for (auto it = init;it != fin;++it) {te.push_back(pair<LL,LL>(it->v, it->r - it->l + 1));}
	sort(te.begin(), te.end());
	for (auto it = te.begin(), fin2 = te.end();it != fin2;++it) {
		k -= it->second;
		if (k <= 0){ return it->first; }
	}
	ch.repair(init); ch.repair(fin);
	return -1;
}

//快速幂
LL fm(LL x, LL y, LL mod) {
	LL ans = 1;
	x = x % mod;
	while (y) {
		if (y & 1)
			ans *= x, ans %= mod;
		x *= x, x %= mod;
		y >>= 1;
	}
	return ans % mod;
}

//求区间的次方和在取模
LL bemod(Chtholly<LL>& ch, LL il, LL ir, LL x, LL y) {
	auto fin = ch.split(ir + 1),init= ch.split(il);
	LL temp = 0;
	for (auto it = init;it != fin;++it) {
		temp += (it->r - it->l + 1) * fm(it->v, x, y);
		temp %= y;
	}
	ch.repair(init); ch.repair(fin);
	return temp;
}


int main(){
	cin >> n>> m>> seed>> vmax;
	LL N, L, R,X,Y=0;Chtholly<LL> ch;
	for (int i = 1; i <= n; ++i) { Y = (rnd() % vmax) + 1; ch.insert(i, i, Y); 	}
    
	for (int i = 1;i <= m;++i) {
		N = (rnd() % 4) + 1;L = (rnd() % n) + 1;R = (rnd() % n) + 1;
		if (L > R) { swap(L,R); }
		if (N == 3) { X = (rnd() % (R - L + 1)) + 1; }else{ X = (rnd() % vmax) + 1; }
		if(N==4){Y= (rnd() % vmax) + 1;}
		function<void(LL&)> add([X](LL& a)->void { a += X; });
		switch (N) {
		case 1:
			ch.cast(L, R, add);break;
		case 2:
			ch.assign(L, R, X);break;
		case 3:
			cout << kth(ch, L, R, X) << "\n";
			break;
		case 4:
			cout << bemod(ch, L, R, X, Y) << "\n";
		}	
	}
	return 0;
}
2021/2/14 02:05
加载中...