版权声明:转载请声明出处,谢谢配合。 https://blog.csdn.net/zxyoi_dreamer/article/details/88784617
传送门
都是套路不想写题解了。
代码:
#include<bits/stdc++.h>
#define int unsigned int
#define re register
#define gc get_char
#define cs const
namespace IO{
inline char get_char(){
static cs int Rlen=1<<20|1;
static char buf[Rlen],*p1,*p2;
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;
}
inline char getalpha(){
re char c;
while(!isalpha(c=gc()));return c;
}
}
using namespace IO;
using std::cout;
using std::cerr;
struct mp{
int first,second;
mp(){}
mp(cs int &_f,cs int &_s):first(_f),second(_s){}
};
typedef mp pii;
int c[11][11];
inline void init(){
for(int re i=0;i<=10;++i){
c[i][0]=c[i][i]=1;
for(int re j=1;j<i;++j)
c[i][j]=c[i-1][j-1]+c[i-1][j];
}
}
cs int N=2e5+5;
int son[N][2],siz[N],val[N];
int ans[N][11];
inline int newnode(cs int &_val){
static int tot;
++tot;
siz[tot]=1;
val[tot]=_val;
for(int re i=0;i<=10;++i)ans[tot][i]=_val;
return tot;
}
inline void pushup(int u){
int lc=son[u][0],rc=son[u][1];
siz[u]=siz[lc]+siz[rc]+1;
static int po[11];
po[0]=1;
for(int re i=1;i<=10;++i)po[i]=po[i-1]*(siz[lc]+1);
for(int re i=0;i<=10;++i){
ans[u][i]=ans[lc][i]+val[u]*po[i];
for(int re j=0;j<=i;++j)
ans[u][i]+=ans[rc][j]*po[i-j]*c[i][j];
}
}
inline pii split(int now,cs int &key){
if(!now)return mp(0,0);
pii res;
if(siz[son[now][0]]+1<=key){
res=split(son[now][1],key-siz[son[now][0]]-1);
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;
}
inline int merge(int a,int b){
if(!a||!b)return a|b;
if((long long)siz[a]*rand()>(long long)siz[b]*rand()){
son[a][1]=merge(son[a][1],b);
pushup(a);
return a;
}
else {
son[b][0]=merge(a,son[b][0]);
pushup(b);
return b;
}
}
int rt;
inline int build(int l,int r){
if(l==r)return newnode(getint());
int mid=(l+r)>>1;
int lc=build(l,mid),rc=build(mid+1,r);
return merge(lc,rc);
}
inline void Ins(int pos,int val){
pii res=split(rt,pos-1);
rt=merge(res.first,merge(newnode(val),res.second));
}
inline void Del(int pos){
pii res1=split(rt,pos-1);
pii res2=split(res1.second,1);
rt=merge(res1.first,res2.second);
}
inline void Change(int pos,int _val){
pii res1=split(rt,pos-1);
pii res2=split(res1.second,1);
rt=merge(res1.first,merge(newnode(_val),res2.second));
}
inline int Query(int l,int r,int k){
pii res1=split(rt,r);
pii res2=split(res1.first,l-1);
int res=ans[res2.second][k];
rt=merge(merge(res2.first,res2.second),res1.second);
return res;
}
int n;
signed main(){
init();
srand(time(0));
rt=build(1,getint());
n=getint();
while(n--)switch(getalpha()){
case 'I':{
int pos=getint()+1,val=getint();
Ins(pos,val);
break;
}
case 'D':Del(getint()+1);break;
case 'R':{
int pos=getint()+1,val=getint();
Change(pos,val);
break;
}
case 'Q':{
int l=getint()+1,r=getint()+1,k=getint();
cout<<Query(l,r,k)<<"\n";
break;
}
}
return 0;
}