Loj 6282. 数列分块入门 6

链接:https://loj.ac/problem/6282

思路:

用动态的vector去代替数组,这样就可以动态的插入数据了,当一个块的数据插入数据过大时,我们在将整个vector重新分块就好了。

实现代码:

#include<bits/stdc++.h>
using namespace std;
const int M = 2e5+10;
vector<int>ve[1005];
int st[M];
int n,m,block;
pair<int,int> query(int len){
    int x = 1;
    while(len > ve[x].size()) len -= ve[x].size(),x++;
    return make_pair(x,len-1); 
} 

void rebuild(){
    int top = 0;
    for(int i = 1;i <= m;i ++){
        for(vector <int>:: iterator j = ve[i].begin();j != ve[i].end();j ++)
            st[++top] = *j;
        ve[i].clear();
    }
    int block2 = sqrt(top);
    for(int i = 1;i <= top;i ++){
        ve[(i-1)/block2+1].push_back(st[i]);
    }
    m = (n-1)/block2+1;
}

void Insert(int p,int c){
    pair<int,int> t = query(p);
    ve[t.first].insert(ve[t.first].begin()+t.second,c);
    if(ve[t.first].size() > 20*block)
    rebuild();
}
int a[M];
int main(){
    int l,r,op,c;
    scanf("%d",&n);
    block = sqrt(n);
    for(int i = 1;i <= n;i ++) scanf("%d",&a[i]);
    for(int i = 1;i <= n;i ++){
        ve[(i-1)/block+1].push_back(a[i]);
    }
    m = (n-1)/block+1;
    for(int i = 1;i <= n;i ++){
        scanf("%d%d%d%d",&op,&l,&r,&c);
        if(op == 0) Insert(l,r);
        else {
            pair<int,int> t = query(r);
            printf("%d
",ve[t.first][t.second]);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/kls123/p/9374928.html