块链板题 数列分块入门 6 求助
  • 板块学术版
  • 楼主Lice
  • 当前回复3
  • 已保存回复3
  • 发布时间2020/6/28 16:22
  • 上次更新2023/11/6 23:57:18
查看原帖
块链板题 数列分块入门 6 求助
61430
Lice楼主2020/6/28 16:22

QAQ

这个重构哪里有问题啊

删了重构就ac了 /yiw

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <utility>
#include <vector>

using namespace std;
const int N = 1e5 + 5;
int n, q;
int num[N];

struct block {
	int l, r;
	vector<int> num;
	block(int l, int r) : l(l), r(r) { }
	inline int size() { return r - l + 1; }
};
vector<block> dat;
int b;

void init() {
	for (register int i = 1; i <= n; i++) {
		if ((i - 1) % b == 0) dat.push_back(block(i, min(i + b - 1, n)));
		dat.rbegin()->num.push_back(num[i]);
	}
}

typedef pair<vector<block>::iterator, vector<int>::iterator> position;
position get(int p) {
	position ret;
	for (ret.first = dat.begin(); ; ret.first++)
		if (ret.first->l <= p && p <= ret.first->r) break;
	ret.second = ret.first->num.begin() + (p - ret.first->l);
	return ret;
}
// |---f---||---x---|
void split(vector<block>::iterator x) {
	vector<block>::iterator f = dat.insert(x, block(x->l, x->l + b - 1));
	x++, x->l += f->size();
	f->num.insert(f->num.end(), x->num.begin(), x->num.begin() + f->size());
	x->num.erase(x->num.begin(), x->num.begin() + f->size());
}

void insert(int p, int v) {
	position pos = get(p);
	pos.first->num.insert(pos.second, v);
	
	pos.first->r++;
	for (vector<block>::iterator it = pos.first + 1; it != dat.end(); it++)
		it->l++, it->r++;
	
	if (pos.first->size() > b * 2)
		split(pos.first);
}

signed main() {
	scanf("%d", &n), q = n;
	b = ceil(sqrt(n * 1.0));
	for (register int i = 1; i <= n; i++)
		scanf("%d", num + i);
	init();
	
	while (q--) {
		int op, l, r, c;
		scanf("%d%d%d%d", &op, &l, &r, &c);
		if (op == 0) insert(l, r);
		else printf("%d\n", *get(r).second);
	}
}
2020/6/28 16:22
加载中...