LibreOJ 6282 数列分块入门 6(在线插入在线查询)

时间:2021-06-02 14:52:57

LibreOJ 6282 数列分块入门 6(在线插入在线查询)

LibreOJ 6282 数列分块入门 6(在线插入在线查询)

题解:还是分块,将每个块存入vector,然后在插入的时候就是sqrt(n)级的重构,如果块太大了,暴力将这个块拆开.

代码如下:

#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std; int a[],tmp[],top;
int n,sz,m;
vector<int> v[]; pair<int,int> query(int x)
{
int pos=;
while(x>v[pos].size())
{
x-=v[pos].size();
pos++;
}
return make_pair(pos,x-);
} void rebuild()
{
top=;
for(int i=;i<=m;i++)
{
for(int j=;j<v[i].size();j++)
{
tmp[++top]=v[i][j];
}
v[i].clear();
}
int sz2=sqrt(top);
for(int i=;i<=top;i++)
{
v[(i-)/sz+].push_back(tmp[i]);
}
m=(top-)/sz2+;
} 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()>*sz)
{
rebuild();
}
} int main()
{
int opt,l,r,c;
scanf("%d",&n);
sz=sqrt(n);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=;i<=n;i++)
{
v[(i-)/sz+].push_back(a[i]);
}
m=(n-)/sz+;
for(int i=;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\n",v[w.first][w.second]);
}
}
}