标签:Willem sit int CF896C ll rnd 朵莉树 split it2
https://www.cnblogs.com/WAMonster/p/10181214.html
主要用于支持含有较难维护的区间操作与查询的问题,要求其中区间赋值操作(assign())是纯随机的。
注意要先split(r+1)再split(l),最好最后设一个点(n+1,n+1,0)
1 #include<set> 2 #include<cstdio> 3 #include<algorithm> 4 #include<iostream> 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 6 typedef long long ll; 7 using namespace std; 8 9 const int N=100010; 10 int n,m,x,y,mx; ll seed; 11 struct P{ int l,r; mutable ll v; }; 12 bool operator <(const P &a,const P &b){ return a.l<b.l; } 13 set<P>S; 14 typedef set<P>::iterator sit; 15 pair<ll,int>ve[N]; 16 17 ll ksm(ll a,ll b,ll mod){ 18 ll res=1; a%=mod; 19 for (; b; a=a*a%mod,b>>=1) 20 if (b & 1) res=res*a%mod; 21 return res; 22 } 23 24 sit split(int pos){ 25 sit it=S.lower_bound((P){pos,0,0}); 26 if (it!=S.end() && it->l==pos) return it; 27 it--; int l=it->l,r=it->r; ll v=it->v; 28 S.erase(it); S.insert((P){l,pos-1,v}); 29 return S.insert((P){pos,r,v}).first; 30 } 31 32 void assign(int l,int r,ll v){ 33 sit it2=split(r+1),it1=split(l); 34 S.erase(it1,it2); S.insert((P){l,r,v}); 35 } 36 37 void add(int l,int r,ll v){ 38 sit it2=split(r+1),it1=split(l); 39 for (sit it=it1; it!=it2; it++) it->v+=v; 40 } 41 42 ll kth(int l,int r,int k){ 43 sit it2=split(r+1),it1=split(l); int tot=0; 44 for (sit it=it1; it!=it2; it++) ve[++tot]=pair<ll,int>(it->v,(it->r)-(it->l)+1); 45 sort(ve+1,ve+tot+1); 46 rep(i,1,tot){ 47 k-=ve[i].second; 48 if (k<=0) return ve[i].first; 49 } 50 return 0; 51 } 52 53 ll que(int l,int r,int x,ll y){ 54 sit it2=split(r+1),it1=split(l); 55 ll res=0; 56 for (sit it=it1; it!=it2; it++) res=(res+((it->r)-(it->l)+1)*ksm(it->v,x,y))%y; 57 return res; 58 } 59 60 int rnd(){ int ret=(int)seed; seed=(seed*7+13)%1000000007; return ret; } 61 62 int main(){ 63 freopen("CF896C.in","r",stdin); 64 freopen("CF896C.out","w",stdout); 65 cin>>n>>m>>seed>>mx; 66 rep(i,1,n) S.insert((P){i,i,rnd()%mx+1}); 67 S.insert((P){n+1,n+1,0}); 68 rep(i,1,m){ 69 int op=rnd()%4+1,l=rnd()%n+1,r=rnd()%n+1; 70 if (l>r) swap(l,r); 71 if (op==3) x=rnd()%(r-l+1)+1; else x=rnd()%mx+1; 72 if (op==4) y=rnd()%mx+1; 73 if (op==1) add(l,r,x); 74 if (op==2) assign(l,r,x); 75 if (op==3) cout<<kth(l,r,x)<<endl; 76 if (op==4) cout<<que(l,r,x,y)<<endl; 77 } 78 return 0; 79 }
标签:Willem,sit,int,CF896C,ll,rnd,朵莉树,split,it2 来源: https://www.cnblogs.com/HocRiser/p/10617173.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。