QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#199940#7347. HDRFDreamOn#ML 1ms7896kbC++142.9kb2023-10-04 14:44:152023-10-04 14:44:15

Judging History

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

  • [2023-10-04 14:44:15]
  • 评测
  • 测评结果:ML
  • 用时:1ms
  • 内存:7896kb
  • [2023-10-04 14:44:15]
  • 提交

answer

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

int read() {
    int x = 0, f = 1;
    char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while('0' <= c && c <= '9') {
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x * f;
}

#define Maxn 100005
#define INF 100000000
struct TMP {int v, id;} tmp[Maxn];
int cmp(TMP fir, TMP sec) {return fir.v < sec.v;}

struct Edge {
    int next, to;
}
edge[Maxn];
int head[Maxn], edge_num, n, val[Maxn], ind[Maxn];
int cnt, dfn[Maxn], siz[Maxn];
int ans[Maxn], tot;

void add_edge(int from, int to) {
    edge[++edge_num].next = head[from];
    edge[edge_num].to = to;
    head[from] = edge_num;
}

struct SEGMENT {
    int l, r, Min;
}
tree[Maxn * 4];

#define lid id << 1
#define rid id << 1 | 1
void build(int id, int l, int r) {
    // cout << id << " " << l << " " << r << endl;
    tree[id].l = l, tree[id].r = r;
    if(l == r) {
        tree[id].Min = val[dfn[l]];
        return;
    }
    int mid = (l + r) >> 1;
    build(lid, l, mid); build(rid, mid + 1, r);
    tree[id].Min = min(tree[lid].Min, tree[rid].Min);
}
int query(int id, int l, int r) {
    // cerr << id << " " << l << " " << r << endl;
    // Sleep(500);
    if(tree[id].l == l && tree[id].r == r) return tree[id].Min;
    int mid = (tree[id].l + tree[id].r) >> 1;
    if(r <= mid) return query(lid, l, r);
    else if(mid < l) return query(rid, l, r);
    else return min(query(lid, l, mid), query(rid, mid + 1, r));
}
void cover(int id, int x) {
    if(tree[id].l == tree[id].r) {
        tree[id].Min = INF;
        return;
    }
    int mid = (tree[id].l + tree[id].r) >> 1;
    if(x <= mid) cover(lid, x);
    else cover(rid, x);
    tree[id].Min = min(tree[lid].Min, tree[rid].Min);
}

void dfs(int u) {
    dfn[u] = ++cnt;
    siz[u] = 1;
    for(int i = head[u]; i; i = edge[i].next) {
        int v = edge[i].to;
        dfs(v);
        siz[u] += siz[v];
    }
}

void solve(int u) {
    while(true) {
        if(siz[u] == 1) break;
        int tmp = query(1, dfn[u] + 1, dfn[u] + siz[u] - 1);
        if(tmp == INF) break;
        
        solve(ind[tmp]);
        // cerr << ind[tmp] << endl;
        // ans[++tot] = ind[tmp];
        // cover(1, dfn[ind[tmp]]);
    }
    ans[++tot] = u;
    cover(1, dfn[u]);
}

int main() {
    n = read();
    for(int i = 2; i <= n; ++i) {
        int p = read();
        add_edge(p, i);
    }
    for(int i = 1; i <= n; ++i) tmp[i].v = read(), tmp[i].id = i;
    sort(tmp + 1, tmp + n + 1, cmp);
    for(int i = 1; i <= n; ++i) val[tmp[i].id] = i;
    for(int i = 1; i <= n; ++i) ind[val[i]] = i;
    dfs(1);
    build(1, 1, n);
    solve(1);
    for(int i = 1; i <= tot; ++i) printf("%d ", ans[i]);
    return 0;
}

详细

Test #1:

score: 100
Accepted
time: 1ms
memory: 7896kb

input:

5
4 4 1 1
3 5 2 1 4

output:

3 2 4 5 1 

result:

ok 5 number(s): "3 2 4 5 1"

Test #2:

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

input:

2
1
1 2

output:

2 1 

result:

ok 2 number(s): "2 1"

Test #3:

score: -100
Memory Limit Exceeded

input:

100
85 42 34 7 48 48 63 90 37 80 26 50 73 6 11 94 90 41 89 44 9 29 71 44 27 52 27 39 6 91 28 25 63 12 24 23 25 7 19 15 69 84 80 37 28 100 1 78 23 72 15 12 91 90 87 52 13 8 42 51 69 46 20 8 32 5 62 35 13 61 63 7 72 15 37 16 89 34 73 93 71 14 74 65 27 51 81 75 94 57 67 13 40 65 35 63 80 28 78
39 56 6 ...

output:


result: