[Libre 6282] 数列分块入门 6 (分块)

原题:传送门

code:

//By Menteur_Hxy
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
#define ll long long
#define f(a,b,c) for(int a=b;a<=c;a++)
using namespace std;

inline ll rd() {
    ll x=0,fla=1; char c=' ';
    while(c>'9' || c<'0') {if(c=='-') fla=-fla; c=getchar();}
    while(c<='9'&&c>='0') x=x*10+c-'0',c=getchar();
    return x*fla;
}

inline void out(ll x){
    int a[25],wei=0;
    if(x<0) putchar('-'),x=-x;
    for(;x;x/=10) a[++wei]=x%10;
    if(wei==0){ puts("0"); return;}
    for(int j=wei;j>=1;--j) putchar('0'+a[j]);
    putchar('\n');
}

const int MAX=100010;
const int INF=0x3f3f3f3f;
int n,top,blo,blo2;
int v[MAX],bo[MAX<<1];
vector <int> ve[1005];

int query(int& a) {
    int x=1;
    for(;a>ve[x].size();a-=ve[x].size(),x++);
    return x;
}

void rebuild() {
    top=0;
    for(int i=1;!ve[i].empty();i++) {
        for(vector <int>::iterator j=ve[i].begin();j!=ve[i].end();j++) 
            bo[++top]=*j;
        ve[i].clear();
    }
    blo2=sqrt(top);
    f(i,1,top) ve[(i-1)/blo2+1].push_back(bo[i]);
}

void insrt(int a,int b) {
    int bl=query(a);
    ve[bl].insert(ve[bl].begin()+a-1,b);
    if(ve[bl].size()>20*blo) rebuild();//这里判断的blo不能用新的blo否则无意义!!!! 
}

int main() {
    n=rd(); blo=sqrt(n);
    f(i,1,n) v[i]=rd();
    f(i,1,n) ve[(i-1)/blo+1].push_back(v[i]);

    f(i,1,n) {
        int opt=rd(),l=rd(),r=rd(),c=rd();
        if(opt) {
            int bl=query(r);
            out(ve[bl][r-1]);
//          out(ve[query(r)][r-1]); 这样写会出现玄学错误QAQ
        }
        else insrt(l,r);
    } 
    return 0;
}
posted @ 2018-04-24 18:29  Menteur_hxy  阅读(109)  评论(0编辑  收藏  举报