QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#617568#9252. Penguins in RefrigeratorError_666#RE 0ms0kbC++234.3kb2024-10-06 16:13:232024-10-06 16:13:24

Judging History

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

  • [2024-10-06 16:13:24]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [2024-10-06 16:13:23]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

#define int long long
#define p1 (p << 1)
#define p2 (p << 1 | 1)

const int N = 1e6 + 10;
const int inf = 1e10;
const int mod = 1000000007;

struct G {
	int v, id;
} g[N];
struct F {
	int l, r;
} f[N];
struct E {
	int nex, to;
} e[N];
struct T {
	int l, r, min;
} t[N * 4];
struct T1 {
	int l, r, sum;
} t1[N * 4];
struct A {
	int id, w;
} d[N];
int n, W, cnt, num;
int p[N], a[N], b[N], c[N * 2], h[N], in[N];

int lsh(int x) {
	return lower_bound(c + 1, c + 1 + cnt, x) - c;
}

void pushup(int p) {
	t[p].min = min(t[p1].min, t[p2].min);
}

void build(int p, int l, int r) {
	if (l == r) {
		t[p] = {l, r, inf};
		return;
	}
	t[p] = {l, r, inf};
	int mid = (l + r) >> 1;
	build(p1, l, mid), build(p2, mid + 1, r);
	pushup(p);
}

void pushup1(int p) {
	t1[p].sum = t1[p1].sum + t1[p2].sum;
}

void build1(int p, int l, int r) {
	if (l == r) {
		t1[p] = {l, r, 0};
		return;
	}
	t1[p] = {l, r, 0};
	int mid = (l + r) >> 1;
	build1(p1, l, mid), build1(p2, mid + 1, r);
	pushup1(p);
}

void upd(int x, int p, int v) {
	if (t[x].l == p && t[x].r == p) {
		t[x] = {p, p, v};
		return;
	}
	int mid = (t[x].l +  t[x].r) >> 1;
	if (p <= mid) upd(x << 1, p, v);
	if (p > mid) upd(x << 1 | 1, p, v);
	pushup(x);
}

void upd1(int x, int p, int v) {
	if (t1[x].l == p && t1[x].r == p) {
		t1[x]= {p, p, v};
		return;
	}
	int mid = (t1[x].l + t1[x].r) >> 1;
	if (p <= mid) upd1(x << 1, p, v);
	if (p > mid) upd1(x << 1 | 1, p, v);
	pushup1(x);
}

int ask(int p, int l, int r) {
	if (l <= t[p].l && t[p].r <= r) return t[p].min;
	int mid = (t[p].l + t[p].r) >> 1;
	if (r <= mid) return ask(p1, l, r);
	else if (l > mid) return ask(p2, l, r);
	else return min(ask(p1, l, r), ask(p2, l, r));
}

int ask1(int p, int l, int r) {
	if (l <= t1[p].l && t1[p].r <= r) return t1[p].sum;
	int mid = (t1[p].l + t1[p].r) >> 1;
	if (r <= mid) return ask1(p1, l, r);
	else if (l > mid) return ask1(p2, l, r);
	else return ask1(p1, l, r) + ask1(p2, l, r);
}

void add(int u, int v) {
	e[++num] = {h[u], v};
	h[u] = num;
}

void dfs(int x) {
	cout << x << ' ';
	vector<int> U;
	for (int i = h[x]; i; i = e[i].nex) U.push_back(e[i].to);
	sort(U.begin(), U.end());
	for (auto u : U) dfs(u);
}

bool cmp1(G x, G y) {
	return x.v > y.v;
}

signed main()
{
	ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
	
	cin >> n >> W;
	for (int i = 1; i <= n; i++) cin >> p[i];
	for (int i = 1; i <= n; i++) {
		d[i].id = i;
		cin >> d[i].w;
	}
	
	for (int i = 1; i <= n; i++) a[i] = d[p[i]].w, b[i] = d[p[i]].id;
	
	for (int i = 1; i <= n; i++) {
		c[++cnt] = a[i];
		c[++cnt] = W - a[i] + 1;
	}
	c[++cnt] = W + 1;
	sort(c + 1, c + 1 + cnt);
	cnt = unique(c + 1, c + 1 + cnt) - c - 1;
	// 建树范围: [1, cnt]
	build(1, 1, cnt);
	build1(1, 0, n + 1);
	
	vector<G> seq;
	
	for (int i = n; i >= 1; i--) {
		// 要从(i+1)往前找到第一个j,使得a[i] + a[j] > W
		// 然后b[j]向b[i]连一条边
		
		// 看看[lsh(W - a[i] + 1) ~ cnt]里的最小值是谁(记为pos)
		// 如果不是inf,则pos -> b[i]
		int pos = ask(1, lsh(W - a[i] + 1), cnt);
		if (pos != inf) add(pos, b[i]), in[b[i]]++;
		
		if (a[i] <= W / 2) {
			if (pos == inf) f[i].r = n + 1;
			else f[i].r = pos;
			seq.push_back((G){a[i], i});
		}
		else upd1(1, i, 1);
		
		// 更新upd(lsh(a[i]), b[i])
		upd(1, lsh(a[i]), b[i]);
	}
	
	build(1, 1, cnt);
	reverse(a + 1, a + 1 + n);
	reverse(b + 1, b + 1 + n);
	for (int i = n; i >= 1; i--) {
		int pos = ask(1, lsh(W - a[i] + 1), cnt);
		
		if (a[i] <= W / 2) {
			if (pos == inf) f[n - i + 1].l = 0;
			else f[n - i + 1].l = n - pos + 1;	
		}
		
		upd(1, lsh(a[i]), b[i]);
	}
	
	// 对于那些 <= W / 2的数,从大到小依次插入。每次ans *= (ask1(1, f[i].l, f[i].r) - 1),然后upd1(1, i, 1)
	int ans = 1;
	sort(seq.begin(), seq.end(), cmp1);
	upd1(1, 0, 1), upd1(1, n + 1, 1);
	for (auto now : seq) {
		int v = now.v;
		int id = now.id;
		ans = ans * ((ask1(1, f[id].l, f[id].r) - 1) % mod);
		ans %= mod;
		upd1(1, id, 1);
	}
	cout << ans % mod << endl;
	
	vector<int> S;
	for (int i = 1; i <= n; i++)
		if (!in[i]) S.push_back(i);
	sort(S.begin(), S.end());
	
	for (auto s : S) dfs(s);
	return 0;
}
/*
5 10
1 2 3 4 5
6 5 3 9 2

5 10
1 2 3 4 5
2 4 3 3 8
*/

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Runtime Error

input:

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

output:


result: