Chtholly Tree
阿新 • • 發佈:2018-12-25
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;
}