传送门
解析:
这种题无脑压节点,剩下的无脑写平衡树暴力就行了。
平衡树做不了的提出来数组做就行了。
没什么难度。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc get_char
#define cs const
namespace IO{
namespace IOONLY{
cs int Rlen=1<<20|1;
char buf[Rlen],*p1,*p2;
}
inline char get_char(){
using namespace IOONLY;
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
}
inline int getint(){
re char c;
while(!isdigit(c=gc()));re int num=c^48;
while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
return num;
}
}
using namespace IO;
inline unsigned int Rand(){
static unsigned int state0=19491001;
state0^=(state0<<13);
state0^=(state0>>17);
state0^=(state0<<5);
return state0;
}
cs int N=500005,INF=0x7fffffff;
namespace FHQ_treap{
namespace Vars{
int son[N][2];
bool rev[N];
ll sum[N];
int val[N],mx[N],mn[N],add[N];
int siz[N],cnt[N];
int tot;
}
inline int newnode(cs int _val,cs int _cnt=1){
using namespace Vars;
int now=++tot;
val[now]=mn[now]=mx[now]=_val;
sum[now]=(ll)_val*_cnt;
siz[now]=cnt[now]=_cnt;
return now;
}
inline void pushup(int now){
using namespace Vars;
siz[now]=siz[son[now][0]]+siz[son[now][1]]+cnt[now];
sum[now]=sum[son[now][0]]+sum[son[now][1]]+(ll)val[now]*cnt[now];
mn[now]=min(val[now],min(mn[son[now][0]],mn[son[now][1]]));
mx[now]=max(val[now],max(mx[son[now][0]],mx[son[now][1]]));
}
inline void pushrev(int now){
using namespace Vars;
rev[now]^=1;
swap(son[now][0],son[now][1]);
}
inline void pushadd(int now,int v){
using namespace Vars;
add[now]+=v;
val[now]+=v;
mx[now]+=v;
mn[now]+=v;
sum[now]+=(ll)siz[now]*v;
}
inline void pushdown(int now){
using namespace Vars;
if(rev[now]){
if(son[now][0])pushrev(son[now][0]);
if(son[now][1])pushrev(son[now][1]);
rev[now]=0;
}
if(add[now]){
if(son[now][0])pushadd(son[now][0],add[now]);
if(son[now][1])pushadd(son[now][1],add[now]);
add[now]=0;
}
}
pair<int,int> split(int now,cs int &key){
using namespace Vars;
if(!now)return make_pair(0,0);
pair<int,int> res;
pushdown(now);
if(siz[son[now][0]]+cnt[now]<=key){
res=split(son[now][1],key-siz[son[now][0]]-cnt[now]);
son[now][1]=res.first;
res.first=now;
}
else {
res=split(son[now][0],key);
son[now][0]=res.second;
res.second=now;
}
pushup(now);
return res;
}
int merge(int lc,int rc){
using namespace Vars;
if(!lc||!rc)return lc+rc;
pushdown(lc);
pushdown(rc);
if(Rand()*siz[lc]>Rand()*siz[rc]){
son[lc][1]=merge(son[lc][1],rc);
pushup(lc);
return lc;
}
else {
son[rc][0]=merge(lc,son[rc][0]);
pushup(rc);
return rc;
}
}
int findlef(int now,int red){
using namespace Vars;
if(son[now][0]){
int re tmp=findlef(son[now][0],red);
pushup(now);
return tmp;
}
else {
cnt[now]-=red;
pushup(now);
return val[now];
}
}
pair<int,int> Get(int now,int key){
using namespace Vars;
pair<int,int> res=split(now,key);
int sz=key-siz[res.first];
if(sz)res.first=merge(res.first,newnode(findlef(res.second,sz),sz));
return res;
}
vector<pair<ll,int> >vec;
void inorder_dfs(int now){
using namespace Vars;
if(!now)return ;
pushdown(now);
inorder_dfs(son[now][0]);
vec.push_back(make_pair(val[now],cnt[now]));
inorder_dfs(son[now][1]);
}
inline void travel(int now){
vec.clear();
inorder_dfs(now);
}
}
using namespace FHQ_treap;
int rt;
inline void insert(int pos,int val){
pair<int,int> res=Get(rt,pos);
rt=merge(res.first,merge(newnode(val,1),res.second));
}
inline void erase(int pos){
pair<int,int> res1=Get(rt,pos-1);
pair<int,int> res2=Get(res1.second,1);
rt=merge(res1.first,res2.second);
}
inline void reverse(int l,int r){
pair<int,int> res1=Get(rt,l-1);
pair<int,int> res2=Get(res1.second,r-l+1);
pushrev(res2.first);
rt=merge(res1.first,merge(res2.first,res2.second));
}
inline void move(int l,int r,int k){
pair<int,int> res1=Get(rt,l-1);
pair<int,int> res2=Get(res1.second,r-l+1-k);
pair<int,int> res3=Get(res2.second,k);
rt=merge(merge(res1.first,res3.first),merge(res2.first,res3.second));
}
inline void add(int l,int r,int val){
pair<int,int> res1=Get(rt,l-1);
pair<int,int> res2=Get(res1.second,r-l+1);
pushadd(res2.first,val);
rt=merge(res1.first,merge(res2.first,res2.second));
}
inline void cover(int l,int r,int val){
pair<int,int> res1=Get(rt,l-1);
pair<int,int> res2=Get(res1.second,r-l+1);
rt=merge(res1.first,merge(newnode(val,r-l+1),res2.second));
}
inline ll query_sum(int l,int r){
pair<int,int> res1=Get(rt,l-1);
pair<int,int> res2=Get(res1.second,r-l+1);
ll res=Vars::sum[res2.first];
rt=merge(res1.first,merge(res2.first,res2.second));
return res;
}
inline int Min_Max(int l,int r){
pair<int,int> res1=Get(rt,l-1);
pair<int,int> res2=Get(res1.second,r-l+1);
int res=Vars::mx[res2.first]-Vars::mn[res2.first];
rt=merge(res1.first,merge(res2.first,res2.second));
return res;
}
inline int nearest(int l,int r,int val){
pair<int,int> res1=Get(rt,l-1);
pair<int,int> res2=Get(res1.second,r-l+1);
travel(res2.first);rt=merge(res1.first,merge(res2.first,res2.second));
re int res=INF;
for(int re i=0;i<vec.size();++i)res=min((ll)res,abs(val-vec[i].first));
return res;
}
inline int query_Kth(int l,int r,int k){
pair<int,int> res1=Get(rt,l-1);
pair<int,int> res2=Get(res1.second,r-l+1);
travel(res2.first);rt=merge(res1.first,merge(res2.first,res2.second));
sort(vec.begin(),vec.end());
re int res,i=0;
while(true){
k-=vec[i].second;
if(k<=0)return vec[i].first;
++i;
}
}
inline int query_Rank(int l,int r,int val){
pair<int,int> res1=Get(rt,l-1);
pair<int,int> res2=Get(res1.second,r-l+1);
travel(res2.first);rt=merge(res1.first,merge(res2.first,res2.second));
re int cnt=0;
for(int re i=0;i<vec.size();++i)cnt+=vec[i].first<val?vec[i].second:0;
return cnt;
}
int n,m;
signed main(){
Vars::mn[0]=INF,Vars::mx[0]=-INF;
n=getint();
for(int re i=1;i<=n;++i)rt=merge(rt,newnode(getint()));
m=getint();
while(m--){
int x,y,val;
switch(getint()){
case 1:x=getint();val=getint();insert(x,val);break;
case 2:erase(getint());break;
case 3:x=getint(),y=getint();reverse(x,y);break;
case 4:x=getint(),y=getint(),val=getint();move(x,y,val);break;
case 5:x=getint(),y=getint(),val=getint();add(x,y,val);break;
case 6:x=getint(),y=getint(),val=getint();cover(x,y,val);break;
case 7:x=getint(),y=getint();cout<<query_sum(x,y)<<'\n';break;
case 8:x=getint(),y=getint();cout<<Min_Max(x,y)<<'\n';break;
case 9:x=getint(),y=getint(),val=getint();cout<<nearest(x,y,val)<<'\n';break;
case 10:x=getint(),y=getint(),val=getint();cout<<query_Kth(x,y,val)<<'\n';break;
case 11:x=getint(),y=getint(),val=getint();cout<<query_Rank(x,y,val)<<'\n';break;
}
}
return 0;
}