题解:还是分块,将每个块存入vector,然后在插入的时候就是sqrt(n)级的重构,如果块太大了,暴力将这个块拆开.
代码如下:
#include<cmath> #include<cstdio> #include<vector> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int a[100010],tmp[200010],top; int n,sz,m; vector<int> v[1010]; pair<int,int> query(int x) { int pos=1; while(x>v[pos].size()) { x-=v[pos].size(); pos++; } return make_pair(pos,x-1); } void rebuild() { top=0; for(int i=1;i<=m;i++) { for(int j=0;j<v[i].size();j++) { tmp[++top]=v[i][j]; } v[i].clear(); } int sz2=sqrt(top); for(int i=1;i<=top;i++) { v[(i-1)/sz+1].push_back(tmp[i]); } m=(top-1)/sz2+1; } void insert(int l,int c) { pair<int,int> w=query(l); v[w.first].insert(v[w.first].begin()+w.second,c); if(v[w.first].size()>20*sz) { rebuild(); } } int main() { int opt,l,r,c; scanf("%d",&n); sz=sqrt(n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } for(int i=1;i<=n;i++) { v[(i-1)/sz+1].push_back(a[i]); } m=(n-1)/sz+1; for(int i=1;i<=n;i++) { scanf("%d%d%d%d",&opt,&l,&r,&c); if(!opt) { insert(l,r); } else { pair<int,int> w=query(r); printf("%d ",v[w.first][w.second]); } } }