QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#617568 | #9252. Penguins in Refrigerator | Error_666# | RE | 0ms | 0kb | C++23 | 4.3kb | 2024-10-06 16:13:23 | 2024-10-06 16:13:24 |
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
*/
詳細信息
Test #1:
score: 0
Runtime Error
input:
5 10 1 2 3 4 5 6 5 3 9 2