[CF896C]Willem, Chtholly and Seniorious(珂朵莉树)

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 }

 

posted @ 2019-03-28 19:36  HocRiser  阅读(368)  评论(0编辑  收藏  举报