CF896C Willem, Chtholly and Seniorious
珂朵莉树\雾
刚开始把每个数都当做一个区间;分裂操作很重要(有些细节);推平时直接 erase
掉区间的 iterator
,单独插一个回去;区间加时把所有 iterator
分裂出来,直接加;区间第 \(k\) 大把区间 \([l,r]\) 里的所有 iterator
取出来按权值 vl
排序;区间 \(k\) 次方我们还是把区间所有的 iterator
取出来然后计算即可。
#include<iostream>
#include<cstdio>
#include<set>
#include<vector>
#include<algorithm>
#define I set<node>::iterator
#define R register int
#define ll long long
using namespace std;
namespace Luitaryi {
inline int g() { R x=0,f=1;
register char s; while(!isdigit(s=getchar())) f=s=='-'?-1:f;
do x=x*10+(s^48); while(isdigit(s=getchar())); return x*f;
} const int M=1000000007,N=100010;
struct node {
int l,r; mutable ll vl;
node(int l,int r=-1,ll vl=0):l(l),r(r),vl(vl) {}
inline bool operator < (const node& that) const {return l<that.l;}
};
inline int qpow(int a,int b,int M) { R ret=1;
for(;b;b>>=1,a=1ll*a*a%M) if(b&1) ret=1ll*ret*a%M; return ret;
}
set<node> s;
inline I split(int pos) {
I it=s.lower_bound(node(pos));
if(it!=s.end()&&it->l==pos) return it;
--it;
R LL=it->l,RR=it->r;
register ll vl=it->vl;
s.erase(it);
s.insert(node(LL,pos-1,vl));
return s.insert(node(pos,RR,vl)).first;
}
inline void add(int l,int r,int vl) {
I RR=split(r+1),LL=split(l);
while(LL!=RR) LL->vl+=vl,++LL;
}
inline void flat(int l,int r,int vl) {
I RR=split(r+1),LL=split(l);
s.erase(LL,RR),s.insert(node(l,r,vl));
}
vector<pair<ll,int> > mem;
inline ll getvl(int l,int r,int k) {
mem.clear();
I RR=split(r+1),LL=split(l);
while(LL!=RR) mem.push_back(make_pair(LL->vl,LL->r-LL->l+1)),++LL;
sort(mem.begin(),mem.end());
for(const auto& v:mem) {
k-=v.second;
if(k<=0) return v.first;
} return -1;
}
inline int query(int l,int r,int b,int M) {
I RR=split(r+1),LL=split(l);
R ret=0;
while(LL!=RR) ret=(ret+1ll*(LL->r-LL->l+1)*qpow(LL->vl%M,b,M))%M,++LL;
return ret;
}
int n,m;
int sed,V;
inline int rnd() {
R ret=sed;
sed=(1ll*sed*7+13)%M;
return ret;
}
inline void main() {
n=g(),m=g(),sed=g(),V=g();
for(R i=1;i<=n;++i)
s.insert(node(i,i,rnd()%V+1));
s.insert(node(n+1,n+1,0));
for(R i=1,op,l,r,x,y;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()%V+1;
if(op==4) y=rnd()%V+1;
if(op==1) add(l,r,x);
if(op==2) flat(l,r,x);
if(op==3) printf("%I64d\n",getvl(l,r,x));
if(op==4) printf("%d\n",query(l,r,x,y));
}
}
} signed main() {Luitaryi::main(); return 0;}
2019.01.16