【题目链接】
LOJ #6282. 数列分块入门 6
【解析】
Splay 。。。
这是分块的题。。。
还是老老实实用分块吧,在每个块内开一个 vector 或 list。
但是当数据不随机时,可能会出现一个块内有很多很多很多很多个元素的情况,这时候需要将每个块重构,或者在 sqrt(n) 次操作后重构,以保证时间复杂度。
【代码】
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
const int maxq = 1e3 + 10;
struct node
{
int s;
int t;
};
int n, a[maxn], q, m;
int s[maxn << 1];
vector<int> e[maxq];
void build()
{
q = sqrt(n), m = (n - 1) / q + 1;
for(int i = 1; i <= n; i++)
e[(i - 1) / q + 1].push_back(a[i]);
}
node query(int u)
{
int i = 1;
while(u > (int)e[i].size() )
u -= (int)e[i].size(), i++;
return (node){ i, u - 1 };
}
void rebuild()
{
int top = 0;
for(int i = 1; i <= m; i++)
{
int z = e[i].size();
for(int j = 0; j < z; j++)
s[++top] = e[i][j];
e[i].clear();
}
q = sqrt(top), m = (top - 1) / q + 1;
for(int i = 1; i <= top; i++)
e[(i - 1) / q + 1].push_back(s[i]);
}
void modify(int u, int k)
{
node x = query(u);
int s = x.s, t = x.t;
e[s].insert(e[s].begin() + t, k);
if( (int)e[s].size() > q * 20)
rebuild();
}
int main()
{
cin >> n;
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]);
build();
for(int i = 1; i <= n; i++)
{
int opt, u, v, c;
scanf("%d%d%d%d", &opt, &u, &v, &c);
if(opt == 0)
modify(u, v);
else
{
node x = query(v);
int s = x.s, t = x.t;
printf("%d\n", e[s][t]);
}
}
return 0;
}