• LOJ-6282-数列分块入门6


    链接:

    https://loj.ac/problem/6282

    题意:

    给出一个长为 的数列,以及 个操作,操作涉及单点插入,单点询问,数据随机生成。

    思路:

    vector 维护每个区间, 当某个区间的值太多时,重构一下.

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    //#include <memory.h>
    #include <queue>
    #include <set>
    #include <map>
    #include <algorithm>
    #include <math.h>
    #include <stack>
    #include <string>
    #include <assert.h>
    #include <iomanip>
    #define MINF 0x3f3f3f3f
    using namespace std;
    typedef long long LL;
    const int MAXN = 1e5+10;
    
    int Belong[MAXN*10], a[MAXN*10];
    vector<int> Vec[MAXN];
    int n, part, last;
    
    pair<int, int> GetPos(int p)
    {
        int p1 = 1;
        while (p > Vec[p1].size())
            p -= Vec[p1].size(), p1++;
        return make_pair(p1, p-1);
    }
    
    void Rebuild()
    {
        int pos = 0;
        for (int i = 1;i <= last;i++)
        {
            for (vector<int>::iterator it = Vec[i].begin();it != Vec[i].end();++it)
                a[++pos] = *it;
            Vec[i].clear();
        }
        part = sqrt(pos);
        last = (pos-1)/part+1;
        for (int i = 1;i <= pos;i++)
        {
            Belong[i] = (i-1)/part+1;
            Vec[Belong[i]].push_back(a[i]);
        }
    }
    
    void Update(int l, int r, int c)
    {
        pair<int, int> p = GetPos(l);
        Vec[p.first].insert(Vec[p.first].begin()+p.second, r);
        if (Vec[p.first].size() > 10*part)
            Rebuild();
    }
    
    int Query(int l, int r, int c)
    {
        pair<int, int> p = GetPos(r);
        return Vec[p.first][p.second];
    }
    
    
    int main()
    {
        scanf("%d", &n);
        part = sqrt(n);
        int v;
        for (int i = 1;i <= n;i++)
        {
            scanf("%d", &v);
            Belong[i] = (i-1)/part+1;
            Vec[Belong[i]].push_back(v);
        }
        last = (n-1)/part+1;//最后一个区间
        int op, l, r, c;
        for (int i = 1;i <= n;i++)
        {
            scanf("%d", &op);
            if (op == 0)
            {
                scanf("%d%d%d", &l, &r, &c);
                Update(l, r, c);
            }
            else
            {
                scanf("%d%d%d", &l, &r, &c);
                printf("%d
    ", Query(l, r, c));
            }
        }
    
        return 0;
    }
    
  • 相关阅读:
    TH-Union教学机 指令总结
    Manjaro 显卡驱动安装
    grub学习内容
    manjaro 折腾
    链栈的实现
    汇编综合实验
    二叉树
    Oracle表空间基本操作
    Windows7/10实现ICMP(ping命令)
    WireShark——IP协议包分析(Ping分析IP协议包)
  • 原文地址:https://www.cnblogs.com/YDDDD/p/11432143.html
Copyright © 2020-2023  润新知