QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#689920#9252. Penguins in Refrigeratorreal_sigma_teamTL 0ms3824kbC++234.6kb2024-10-30 19:14:052024-10-30 19:14:07

Judging History

你现在查看的是最新测评结果

  • [2024-10-30 19:14:07]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:3824kb
  • [2024-10-30 19:14:05]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

constexpr int mod = 1'000'000'007;

mt19937 mt(852095);

int add(int a, int b) {
	return a + b >= mod ? a + b - mod : a + b;
}

int sub(int a, int b) {
	return a >= b ? a - b : a + mod - b;
}

int mul(int a, int b) {
	return 1ll * a * b % mod;
}

struct node {
	int v, mx, sz, l, r, y, w;
	pair<int, int> mnw, mxw;
	node() {
		mnw = {INT32_MAX / 2, -1};
		mxw = {-1, -1};
		w = -1;
		v = -1;
		mx = -1;
		sz = 1;
		l = 0;
		r = 0;
		y = mt();
	}
};

struct treap {
	vector<node> tr;
	treap() {
		tr.clear();
		tr.emplace_back();
		tr[0].y = 0;
		tr[0].sz = 0;
	}
	void update(int i) {
		if (!i) {
			return;
		}
		tr[i].sz = 1 + tr[tr[i].l].sz + tr[tr[i].r].sz;
		tr[i].mx = max({tr[tr[i].l].mx, tr[tr[i].r].mx, tr[i].v});
		tr[i].mxw = max({tr[tr[i].l].mxw, make_pair(tr[tr[i].r].mxw.first, tr[tr[i].r].mxw.second + tr[tr[i].l].sz + 1), make_pair(tr[i].w, tr[tr[i].l].sz)});
		tr[i].mnw = min({tr[tr[i].l].mnw, make_pair(tr[tr[i].r].mnw.first, tr[tr[i].r].mnw.second + tr[tr[i].l].sz + 1), make_pair(tr[i].w, tr[tr[i].l].sz)});
	}
	pair<int, int> split(int i, int sz) {
		if (!i) {
			return {0, 0};
		}
		if (!sz) {
			return {0, i};
		}
		if (sz == tr[i].sz) {
			return {i, 0};
		}
		if (tr[tr[i].l].sz >= sz) {
			auto [nl, nr] = split(tr[i].l, sz);
			tr[i].l = nr;
			update(i);
			return {nl, i};
		}
		auto [nl, nr] = split(tr[i].r, sz - tr[tr[i].l].sz - 1);
		tr[i].r = nl;
		update(i);
		return {i, nr};
	}
	pair<int, int> splitv(int i, int v) {
		if (!i) {
			return {0, 0};
		}
		if (tr[i].mx < v) {
			return {i, 0};
		}
		if (tr[tr[i].l].mx >= v || tr[i].v >= v) {
			auto [nl, nr] = splitv(tr[i].l, v);
			tr[i].l = nr;
			update(i);
			return {nl, i};
		}
		auto [nl, nr] = splitv(tr[i].r, v);
		tr[i].r = nl;
		update(i);
		return {i, nr};
	}
	int merge(int a, int b) {
		if (a == 0) {
			return b;
		}
		if (b == 0) {
			return a;
		}
		if (tr[a].y > tr[b].y) {
			tr[a].r = merge(tr[a].r, b);
			update(a);
			return a;
		}
		tr[b].l = merge(a, tr[b].l);
		update(b);
		return b;
	}
	int insert(int root, int i) {
		if (root == 0) {
			return i;
		}
		if (tr[i].y > tr[root].y) {
			auto [nl, nr] = splitv(root, tr[i].v);
			tr[i].l = nl;
			tr[i].r = nr;
			update(i);
			return i;
		}
		if (tr[tr[root].l].mx >= tr[i].v || tr[root].v >= tr[i].v) {
			tr[root].l = insert(tr[root].l, i);
			update(root);
			return root;
		}
		tr[root].r = insert(tr[root].r, i);
		update(root);
		return root;
	}
	int add_val(int v, int w) {
		int res = tr.size();
		tr.emplace_back();
		tr[res].v = tr[res].mx = v;
		tr[res].mxw = tr[res].mnw = {w, 0};
		tr[res].w = w;
		return res;
	}
	void dfs(int root, vector<int>& ans) {
		if (!root) {
			return;
		}
		dfs(tr[root].l, ans);
		ans.push_back(tr[root].v);
		dfs(tr[root].r, ans);
	}
	void dfs2(int root, vector<int>& ans) {
		if (!root) {
			return;
		}
		dfs2(tr[root].l, ans);
		ans.push_back(root);
		dfs2(tr[root].r, ans);
	}
	node& operator[](int i) {
		return tr[i];
	}
};

constexpr int N = 200200;
int a[N], w[N], W;
treap tr;

pair<int, int> rec(int root) {
	if (root == 0) {
		return {1, 0};
	}
	auto [mn, mni] = tr[root].mnw;
	auto [mx, mxi] = tr[root].mxw;
	if (mx + mn > W) {
		auto [r1, rhui] = tr.split(root, mxi);
		auto [r, r2] = tr.split(rhui, 1);
		auto [cnt1, r3] = rec(r1);
		auto [cnt2, r4] = rec(r2);
		int cnt = mul(cnt1, cnt2);
		root = tr.merge(r3, r);
		root = tr.merge(root, r4);
		return {cnt, root};
	}
	auto [r1, rhui] = tr.split(root, mni);
	auto [r, r2] = tr.split(rhui, 1);
	root = tr.merge(r1, r2);
	auto [cnt, r4] = rec(root);
	root = tr.insert(r4, r);
	// if (W != 96) {
		vector<int> t;
		tr.dfs2(root, t);
		// cout << r << ' ' << tr[r].v << '\n';
		for (int i = 0; i < t.size(); i++) {
			// cout << " (" << t[i] << ' ' << tr[t[i]].v << ") ";
			if (t[i] == r) {
				if (i + 1 < t.size()) {
					assert(tr[t[i]].v < tr[t[i + 1]].v);
				}
				break;
			} else {
				assert(tr[t[i]].v < tr[r].v);
			}
		}
		// cout << '\n';
	// }
	cnt = mul(cnt, tr[root].sz);
	return {cnt, root};
}

int32_t main() {
	// std::cin.tie(nullptr)->sync_with_stdio(false);
	
	int n;
	cin >> n >> W;
	int root = 0;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	for (int i = 0; i < n; i++) {
		cin >> w[i];
	}
	reverse(a, a + n);
	reverse(w, w + n);
	for (int i = 0; i < n; i++) {
		root = tr.merge(root, tr.add_val(a[i], w[i]));
	}
	auto [cnt, r] = rec(root);
	vector<int> ans;
	tr.dfs(r, ans);
	cout << cnt << '\n';
	for (int i = 0; i < n; i++) {
		cout << ans[i] << ' ';
	}
	cout << '\n';
}

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 3604kb

input:

5 10
1 2 3 4 5
6 5 3 9 2

output:

3
5 4 2 1 3 

result:

ok 2 lines

Test #2:

score: 0
Accepted
time: 0ms
memory: 3540kb

input:

5 10
1 2 3 4 5
2 4 3 3 8

output:

30
1 5 2 3 4 

result:

ok 2 lines

Test #3:

score: 0
Accepted
time: 0ms
memory: 3596kb

input:

5 10
1 2 3 4 5
2 3 4 5 1

output:

120
1 2 3 4 5 

result:

ok 2 lines

Test #4:

score: 0
Accepted
time: 0ms
memory: 3824kb

input:

5 10
1 2 3 4 5
2 3 4 5 6

output:

60
1 2 3 5 4 

result:

ok 2 lines

Test #5:

score: -100
Time Limit Exceeded

input:

100000 96
1996 78922 45321 68844 32404 82013 66552 81163 17216 48170 35495 56660 13480 43118 23173 47257 50168 87069 26167 67231 31758 25694 61063 56642 8923 7727 54528 96554 38964 7604 6822 16256 45300 58869 31359 48638 87645 14779 81505 59585 89293 9291 7002 31810 84701 77648 78295 42595 11394 479...

output:


result: