Chtholly Tree

版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/85232006

CF896C Willem, Chtholly and Seniorious

题目

https://www.luogu.org/problemnew/show/CF896C

题解

https://www.luogu.org/blog/blaze/solution-cf896c
要记得学习这篇博客,毕竟这个是珂朵莉树。。。。。。。。

代码

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
	int f=1,x=0;
	char ch=getchar();
	while (!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar(); }
	while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
	return x*f;
}

//珂朵莉树的节点
template<typename _Tp>
struct chtholly_node
{
	typedef _Tp ll;
	mutable int l,r;
	mutable ll v;
	chtholly_node(int L,int R,ll x):l(L),r(R),v(x){ }
	bool operator < (const chtholly_node& x) const
	{
		return l < x.l;
	}
};

//珂朵莉树的构造
template<typename _Tp>
struct chtholly_tree : public set<chtholly_node<_Tp> >
{
	typedef _Tp ll;
	typedef chtholly_node<ll> node;
	typedef typename set<chtholly_node<ll> >::iterator it;

	//珂朵莉树的操作
	it split(int pos)
	{
		it itl=this->lower_bound(node(pos,-1,ll()));
		if (itl!=this->end() && itl->l==pos) return itl;
		--itl;
		it itr=this->insert(node(pos,itl->r,itl->v)).first;
		itl->r=pos-1;
		return itr;
	}
	void assign(int l,int r,ll x)
	{
		it itl=this->split(l),itr=this->split(r+1);
		this->erase(itl,itr);
		this->insert(node(l,r,x));
	}
};

//珂朵莉树的声明
typedef long long ll;
typedef chtholly_tree<ll> tree;
typedef tree::node node;
typedef tree::it it;
tree T;

//珂朵莉树的维护
void add(int l,int r,ll x)
{
	it itl=T.split(l),itr=T.split(r+1);
	for ( ;itl!=itr;++itl)
		itl->v+=x;
}
void change(int l,int r,ll x)
{
	T.assign(l,r,x);
}
ll select(int l,int r,ll x)
{
	it itl=T.split(l),itr=T.split(r+1);
	vector<pair<ll, int> >vp;
	for ( ;itl!=itr;++itl)
		vp.push_back(pair<ll,int>(itl->v,itl->r - itl->l+1));
	sort(vp.begin(),vp.end());
	for (vector<pair<ll,int> >::iterator it=vp.begin();it!=vp.end();++it)
		if ((x-=it->second)<=0)
			return it->first;
	return -1;
}
ll pow(ll x,ll y,ll m)
{
	ll res=1,ans=x%m;
	while (y)
	{
		if (y&1) res=res*ans%m;
		ans=ans*ans%m;
		y>>=1;
	}
	return res;
}
ll sum(int l,int r,ll x,ll y)
{
	it itl=T.split(l),itr=T.split(r+1);
	ll res=0;
	for ( ;itl!=itr;++itl)
		res=(res+(itl->r-itl->l+1)*pow(itl->v,x,y))%y;
	return res;
}

ll n,m,seed,vmax;
ll rnd()
{
	ll ret=seed;
	seed=(seed*7+13)%1000000007;
	return ret;
}

int main()
{
	n=read(),m=read(),seed=read(),vmax=read();
	//珂朵莉树的初始化
	for (int i=1;i<=n;++i)
		T.insert(node(i,i,rnd()%vmax+1));

	for (int i=1;i<=m;++i)
	{
		int op=rnd()%4+1,l=rnd()%n+1,r=rnd()%n+1,x,y;
		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;
		switch (op)
		{
			case 1:
				add(l,r,x);
				break;
			case 2:
				change(l,r,x);
				break;
			case 3:
				printf("%lld\n",select(l,r,x));
				break;
			case 4:
				printf("%lld\n",sum(l,r,x,y));
				break;
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/huashuimu2003/article/details/85232006