这种题也可以用分块!
用 vector 维护每个整块内的元素,利用内置 insert 函数可以很方便的插入,但不要忘记 vector 是从下标 0 处开始计数
当 vector 内的元素个数大于一定程度时,需要重新分块,因为 vector 插入的复杂度较高
const int N=1e5+5;
int i,j,k;
int n,m,t;
int a[N<<1],block,num; //不断插入元素,数组开大一点
vector<int> v[N];
void build()
{
block=sqrt(n);
num=n/block; if(n%block) num++;
for(int i=1;i<=num;i++){
int l=(i-1)*block+1;
int r=min(block*i,n);
for(int j=l;j<=r;j++) v[i].pb(a[j]);
}
}
void rebuild()
{
n=0;
for(int i=1,len=v[i].size();i<=num;i++){
for(int j=0;j<len;j++){
a[++n]=v[i][j];
}
v[i].clear();
}
build();
}
pii query(int pos)
{
pii p;
int cur=1;
while(v[cur].size()<pos) pos-=v[cur++].size(); //注意判断条件是 <,不是 <=
return make_pair(cur,pos-1);
}
void update(int pos,int w)
{
pii p=query(pos);
int x=p.fr,cnt=p.sc;
v[x].insert(v[x].begin()+cnt,w); //在 begin+cnt 之前插入 w
if(v[x].size()>block*10) rebuild();
}
int main()
{
//IOS;
while(~sd(n)){
for(int i=1;i<=n;i++) sd(a[i]);
build(); m=n;
while(m--){
int opt=read(),l=read(),r=read(),w=read();
if(opt){ pii ans=query(r); pd(v[ans.fr][ans.sc]); }
else update(l,r);
}
}
//PAUSE;
return 0;
}