ODT(珂朵莉树)
作者:互联网
洛谷题解上说珂朵莉是最可爱的女孩,XX不服,于是发表了这篇ODT模板
原题 CF896C
#include <cstdio> #include <set> #include <vector> #include <algorithm> #include <cmath> #include <cstring> #include <string> #include <map> #define M mutable #define P pair<ll,ll> #define VIT vector<P>::iterator #define IT set<node>::iterator //宏定义set的迭代器 #define debug() puts("我喜欢李靖妍") using namespace std; typedef long long ll; const ll mod=1e9+7; ll n,m,seed,vmax; struct node { ll l,r; M ll val; //不写mutable ? RE伺候你 node(ll L,ll R=-1,ll V=0):l(L),r(R),val(V){} bool operator < (const node& ljy) const { return l<ljy.l;//就查左区间 } }; set<node> s; bool cmp(P x,P y) { return x.first<y.first; } IT split(int now) { IT it=s.lower_bound(node(now));//set里也有lowerbound if(it!=s.end()&&it->l==now) { return it; } it--; int l=it->l,r=it->r; ll V=it->val; s.erase(it); s.insert(node(l,now-1,V)); return s.insert(node(now,r,V)).first; } void add(int l,int r,int v) { IT lef=split(l),ri=split(r+1); for(;lef!=ri;lef++) lef->val+=v;//+= } void change(int l,int r,int v) { IT lef=split(l),ri=split(r+1); s.erase(lef,ri); s.insert(node(l,r,v)); } ll _sort(ll l,ll r,ll k) { vector<P> v; v.clear(); IT lef=split(l),ri=split(r+1); for(;lef!=ri;lef++) { ll lle=lef->l,rr=lef->r,val=lef->val; v.push_back(P(val,rr-lle+1)); } sort(v.begin(),v.end(),cmp); for(VIT it=v.begin();it!=v.end();it++) { k-=it->second; if(k<=0) return it->first; } return -1; } ll ksm(ll x,ll y,ll Mod) { x=x%Mod; ll ans=1; while(y) { if(y&1) ans=ans*x%Mod; x=x*x%Mod; y>>=1; } return ans; } ll cal(int l,int r,int x,int y) { IT lef=split(l),ri=split(r+1); ll ans=0; for(;lef!=ri;lef++) { ll lle=lef->l,rr=lef->r,val=lef->val; ans=(ans+(rr-lle+1)*ksm(val,x,y)%y)%y; } return ans; } ll rnd() { ll ret=seed; seed=(seed*7+13)%mod; return ret; } int main() { ll op,l,r,x,y; scanf("%lld%lld%lld%lld",&n,&m,&seed,&vmax); for(ll i=1,tmp;i<=n;i++) { tmp=rnd()%vmax+1; s.insert((node){i,i,tmp}); } for(ll i=1;i<=m;i++) { op=(rnd()%4)+1; l=(rnd()%n)+1; r=(rnd()%n)+1; 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; if(op==1) { add(l,r,x); continue; } if(op==2) { change(l,r,x); continue; } if(op==3) { printf("%lld\n",_sort(l,r,x)); continue; } if(op==4) { printf("%lld\n",cal(l,r,x,y)); continue; } } return 0; }
需要注意的几点
1.OI禁止使用auto 所以宏定义IT
2.split时应该先做右区间,再做左区间
3.LJY 才是最可爱的女孩
标签:return,lef,val,int,ll,ODT,朵莉树,split 来源: https://www.cnblogs.com/btjzoi/p/11722468.html