ODT 珂朵莉树 入门
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<set> #define LL long long using namespace std; const int N = 1e5+6,mod=1e9+7; struct node{ int l,r; mutable LL v; node(int L,int R,LL V):l(L),r(R),v(V){} inline bool operator < (const node& b)const{return l<b.l;} }; set<node>s; int n,m; LL a[N],seed,vmax; inline LL Rand(){ LL ret = seed; seed = (seed*7 + 13)%mod; return ret; } ///快速幂 inline LL qpow(LL a,LL n,LL p){ LL ans=1LL;a%=p; while(n){ if(n&1)ans=ans*a%p; a=a*a%p; n>>=1; } return ans; } typedef set<node>::iterator IT; inline IT split(int pos){ ///把pos位置的区间分成左右两节 IT it = s.lower_bound(node(pos,pos,1)); if(it!=s.end() && it->l==pos)return it; ///如果已经分好了 直接返回 ///否则 我们找到这个区间的前一个区间 也就是l<pos 的区间 --it; ///将这个区间给分裂成 [l,pos-1] ///将这个区间给分裂成 [pos,r] int l=it->l,r=it->r;LL v=it->v; s.erase(it); s.insert(node(l,pos-1,v)); return s.insert(node(pos,r,v)).first; } ///暴力区间加 直接把这个区间内的数全部+V inline void add(int l,int r,LL v){ IT it1 = split(l),it2=split(r+1); for(;it1!=it2;++it1)it1->v+=v; } ///区间赋值 inline void assigns(int l,int r,LL v){ ///把区间断成[1-l-1] [l,r] [r+1,n] IT it1 = split(l),it2=split(r+1); ///清除[l,r]的多余的区间 s.erase(it1,it2); ///加入新赋值的区间 s.insert(node(l,r,v)); } ///区间第K大 inline void Rank(int l,int r,int k){ IT it1=split(l),it2=split(r+1); vector<pair<LL,int> >t; for (;it1!=it2;++it1)t.push_back(pair<LL,int>(it1->v,it1->r - it1->l +1)); sort(t.begin(),t.end()); LL ans=0; for (auto it : t){ ///便利类似容器的begin 到 end 可以直接用auto if (k<=it.second){ ans=it.first; break; }else { k-=it.second; } } printf("%lld\n",ans); } inline void sum(int l,int r,int x,int p){ IT it1=split(l),it2=split(r+1); LL ans=0; for(;it1!=it2;++it1)ans=(ans+(LL)(it1->r - it1->l+1)*qpow(it1->v,x,p))%p; printf("%lld\n",ans); } int main(){ scanf("%d%d%lld%lld",&n,&m,&seed,&vmax); for(int i=1;i<=n;i++){ a[i]=Rand()%vmax+1; s.insert(node(i,i,a[i])); } s.insert(node(n+1,n+1,0)); for(int i=1;i<=m;i++){ int opt=Rand()%4+1; int l=Rand()%n+1; int r=Rand()%n+1; if(l>r)swap(l,r); int x=0,y=0; if(opt==3)x=Rand()%(r-l+1)+1; else x=Rand()%vmax+1; if(opt==4)y=Rand()%vmax+1; if(opt==1)add(l,r,x); else if (opt==2)assigns(l,r,x); else if (opt==3)Rank(l,r,x); else sum(l,r,x,y); } return 0; }
有不懂欢迎咨询
QQ:1326487164(添加时记得备注)