zoukankan      html  css  js  c++  java
  • LOJ 数列分块入门 6

    \(\text{Solution}\)

    涉及到插入,分块需要动态维护块内的元素及相对位置
    于是妙用 \(\text{vector}\)
    学到了 \(insert\) 操作,在某个迭代器前插入元素
    这样我们对元数列分块,块长 \(\sqrt n\)
    每个块用 \(\text{vector}\) 维护
    插入时一块一块地找到合适块的合适位置,用 \(insert\) 插入容器(复杂度与插入位置到末元素长度线性相关)

    \(\text{Solution}\)

    #include <cstdio> 
    #include <vector>
    #include <cmath>
    #define re register
    using namespace std;
    
    const int N = 1e5 + 5;
    int n, a[N], st[N], ed[N], id[N];
    vector<int> Q[N];
    
    inline void prepare()
    {
    	int num = sqrt(n);
    	for(re int i = 1; i <= num; i++)
    	{
    		st[i] = ed[i - 1] + 1, ed[i] = (i == num ? n : ed[i - 1] + n / num);
    		for(re int j = st[i]; j <= ed[i]; j++) id[j] = i;
    	}
    	for(re int i = 1; i <= n; i++) Q[id[i]].push_back(a[i]);
    }
    inline void Insert(int x, int v)
    {
    	int cur = 0, p = 0;
    	while (cur < x) cur += Q[++p].size();
    	Q[p].insert(Q[p].begin() + Q[p].size() - cur + x - 1, v);
    }
    inline int Query(int x)
    {
    	int cur = 0, p = 0;
    	while (cur < x) cur += Q[++p].size();
    	return Q[p][Q[p].size() - cur + x - 1];
    }
    
    int main()
    {
    	scanf("%d", &n);
    	for(re int i = 1; i <= n; i++) scanf("%d", &a[i]);
    	prepare();
    	for(re int i = 1, op, l, r, c; i <= n; i++)
    	{
    		scanf("%d%d%d%d", &op, &l, &r, &c);
    		if (!op) Insert(l, r);
    		else printf("%d\n", Query(r));
    	}
    }
    
  • 相关阅读:
    BZOJ 1013: [JSOI2008]球形空间产生器sphere
    BZOJ 1012: [JSOI2008]最大数maxnumber
    BZOJ 1011: [HNOI2008]遥远的行星
    BZOJ 1008: [HNOI2008]越狱
    BZOJ 1007: [HNOI2008]水平可见直线
    BZOJ 1003: [ZJOI2006]物流运输
    Spark core 总结
    SparkRDD算子(transformations算子和actions算子)
    SparkRDD算子初识
    初识Spark
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/15577183.html
Copyright © 2011-2022 走看看