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


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

    代码如下:

    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    int a[100010],tmp[200010],top;
    int n,sz,m;
    vector<int> v[1010];
    
    pair<int,int> query(int x)
    {
        int pos=1;
        while(x>v[pos].size())
        {
            x-=v[pos].size();
            pos++;
        }
        return make_pair(pos,x-1);
    }
    
    void rebuild()
    {
        top=0;
        for(int i=1;i<=m;i++)
        {
            for(int j=0;j<v[i].size();j++)
            {
                tmp[++top]=v[i][j];
            }
            v[i].clear();
        }
        int sz2=sqrt(top);
        for(int i=1;i<=top;i++)
        {
            v[(i-1)/sz+1].push_back(tmp[i]);
        }
        m=(top-1)/sz2+1;
    }
    
    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()>20*sz)
        {
            rebuild();
        }
    }
    
    int main()
    {
        int opt,l,r,c;
        scanf("%d",&n);
        sz=sqrt(n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        for(int i=1;i<=n;i++)
        {
            v[(i-1)/sz+1].push_back(a[i]);
        }
        m=(n-1)/sz+1;
        for(int i=1;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
    ",v[w.first][w.second]);
            }
        }
    }
  • 相关阅读:
    php-管理变量
    php-变量的间接引用
    php-eval()
    HTML
    php观
    笔记1
    脚本语言
    Windows Server 2012如何把快捷方式加到启动文件夹中
    VIM的笔记
    mongodb 从3.0 升级到3.2
  • 原文地址:https://www.cnblogs.com/stxy-ferryman/p/8560551.html
Copyright © 2020-2023  润新知