QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#617566 | #9252. Penguins in Refrigerator | Error_666# | RE | 64ms | 37244kb | C++23 | 4.3kb | 2024-10-06 16:11:59 | 2024-10-06 16:11:59 |
Judging History
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 * 2];
struct F {
int l, r;
} f[N * 2];
struct E {
int nex, to;
} e[N * 2];
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 * 2];
int n, W, cnt, num;
int p[N * 2], a[N * 2], b[N * 2], c[N * 2], h[N * 2], in[N * 2];
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);
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: 100
Accepted
time: 0ms
memory: 22244kb
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: 22252kb
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: 19924kb
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: 21908kb
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: 0
Accepted
time: 64ms
memory: 37244kb
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:
457992974 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 10...
result:
ok 2 lines
Test #6:
score: -100
Runtime Error
input:
100000 84 93330 3894 94859 22134 49668 30606 26739 82976 76701 56323 75537 7626 87226 20857 98177 21811 70827 75898 8111 48223 26186 64222 63002 79024 19126 41638 1048 43857 25379 19764 60207 27675 77665 66327 6274 34861 30287 13449 64505 51490 5804 65843 49014 85795 12365 31565 34411 71697 66568 28...