LOJ 數列分塊入門 6
阿新 • • 發佈:2021-11-19
\(\text{Solution}\)
涉及到插入,分塊需要動態維護塊內的元素及相對位置
於是妙用 \(\text{vector}\)
學到了 \(insert\) 操作,在某個迭代器前插入元素
這樣我們對元數列分塊,塊長 \(\sqrt n\)
每個塊用 \(\text{vector}\) 維護
插入時一塊一塊地找到合適塊的合適位置,用 \(insert\) 插入容器(複雜度與插入位置到末元素長度線性相關)
\(\text{Solution}\)
#include <cstdio> #include <vector> #include <cmath> #define re register using namespace std; const int N = 1e5 + 5; int n, a[N], st[N], ed[N], id[N]; vector<int> Q[N]; inline void prepare() { int num = sqrt(n); for(re int i = 1; i <= num; i++) { st[i] = ed[i - 1] + 1, ed[i] = (i == num ? n : ed[i - 1] + n / num); for(re int j = st[i]; j <= ed[i]; j++) id[j] = i; } for(re int i = 1; i <= n; i++) Q[id[i]].push_back(a[i]); } inline void Insert(int x, int v) { int cur = 0, p = 0; while (cur < x) cur += Q[++p].size(); Q[p].insert(Q[p].begin() + Q[p].size() - cur + x - 1, v); } inline int Query(int x) { int cur = 0, p = 0; while (cur < x) cur += Q[++p].size(); return Q[p][Q[p].size() - cur + x - 1]; } int main() { scanf("%d", &n); for(re int i = 1; i <= n; i++) scanf("%d", &a[i]); prepare(); for(re int i = 1, op, l, r, c; i <= n; i++) { scanf("%d%d%d%d", &op, &l, &r, &c); if (!op) Insert(l, r); else printf("%d\n", Query(r)); } }