QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#589584#7736. Red Black TreeetherealUnicornTL 1ms6144kbC++142.8kb2024-09-25 18:44:012024-09-25 18:44:01

Judging History

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

  • [2024-09-25 18:44:01]
  • 评测
  • 测评结果:TL
  • 用时:1ms
  • 内存:6144kb
  • [2024-09-25 18:44:01]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

typedef vector<int> vi;

const int N = 1e5 + 10;

struct Dif
{
    vi pos, neg;
    int base, cnt_zero, sum_neg;

    Dif(int base) : base(base), cnt_zero(0), sum_neg(0) {};
    int size() { return pos.size() + neg.size() + cnt_zero; }
    int at(int no)
    {
        if (no <= neg.size())
            return neg[no - 1];
        no -= neg.size();
        if (no <= cnt_zero)
            return 0;
        no -= cnt_zero;
        return pos[pos.size() - no];
    }
    void insert(int x)
    {
        if (x == 1)
            pos.push_back(x);
        else if (x == -1)
        {
            neg.push_back(x);
            sum_neg += x;
        }
        else
            assert(0);
    }
    void merge(Dif dif)
    {
        if (this->size() == 0)
        {
            dif.base += this->base;
            (*this) = dif;
            return;
        }
        int sz = min(dif.size(), this->size());
        vi tmp;
        for (int i = 1; i <= sz; i++)
            tmp.push_back(this->at(i) + dif.at(i));
        (*this) = Dif(base + dif.base);
        for (auto i : tmp)
        {
            if (i > 0)
                pos.push_back(i);
            else if (i == 0)
                cnt_zero++;
            else
            {
                neg.push_back(i);
                sum_neg += i;
            }
        }
        reverse(pos.begin(), pos.end());
    }
    void print()
    {
        cout << "size = " << this->size() << endl;
        cout << "base = " << base << endl;
        cout << "cnt_zero = " << cnt_zero << endl;
        cout << "sum_neg = " << sum_neg << endl;
        for (int i = 1; i <= this->size(); i++)
            cout << this->at(i) << " ";
        cout << endl;
    }
};

vi G[N];
int ans[N];
string color;

void init(int n);
Dif solve(int u);

int main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t, n;
    cin >> t;
    while (t--)
    {
        cin >> n;
        init(n);
        solve(1);
        for (int i = 1; i <= n; i++)
            cout << ans[i] << (i == n ? "\n" : " ");
    }
    return 0;
}

void init(int n)
{
    cin >> color;
    for (int i = 1; i <= n; i++)
        G[i].clear();
    int par;
    for (int i = 2; i <= n; i++)
    {
        cin >> par;
        G[par].push_back(i);
    }
}

Dif solve(int u)
{
    Dif dif = Dif(color[u - 1] - '0');
    for (auto v : G[u])
    {
        Dif tmp = solve(v);
        dif.merge(tmp);
    }
    dif.insert(color[u - 1] == '0' ? 1 : -1);
    ans[u] = dif.base + dif.sum_neg;
    // cout << "======================" << endl;
    // cout << "dif of vertex " << u << endl;
    // dif.print();
    // cout << "======================" << endl;
    return dif;
}

详细

Test #1:

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

input:

2
9
101011110
1 1 3 3 3 6 2 2
4
1011
1 1 3

output:

4 1 2 0 0 0 0 0 0
2 0 0 0

result:

ok 2 lines

Test #2:

score: -100
Time Limit Exceeded

input:

6107
12
000000001000
1 2 3 2 5 4 4 7 3 8 11
19
1100111101111011110
1 2 1 1 4 5 2 4 3 2 2 7 10 2 11 3 15 5
7
0111110
1 1 2 2 1 5
3
000
1 1
7
1000011
1 2 3 3 5 4
7
0001001
1 1 1 3 5 3
8
00111000
1 1 3 2 5 2 7
11
11111110111
1 1 1 4 5 4 5 2 5 1
15
110101101000010
1 2 3 2 1 5 2 5 6 5 8 7 9 14
10
0101000...

output:

1 1 1 1 0 0 0 0 0 0 0 0
6 2 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0
0 0 0
0 0 0 0 0 0 0
2 0 1 0 0 0 0
2 1 0 0 0 0 0 0
4 0 0 2 1 0 0 0 0 0 0
4 3 0 0 2 0 0 0 0 0 0 0 0 0 0
2 0 1 0 0 0 0 0 0 0
6 5 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0
1 1 0 0 0
5 1 0 1 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0
5 3 ...

result: