QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#608645#9373. Query on TreeUltramanBlazerWA 37ms3900kbC++2010.5kb2024-10-04 00:28:552024-10-04 00:28:55

Judging History

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

  • [2024-10-04 00:28:55]
  • 评测
  • 测评结果:WA
  • 用时:37ms
  • 内存:3900kb
  • [2024-10-04 00:28:55]
  • 提交

answer

#include <bits/stdc++.h>

using ll = long long;
using uint = unsigned int;
using ull = unsigned long long;

#define lowbit(x) (x & (-x))
const int mod = 998244353;
const double PI = 3.14159265358;
std::mt19937 rng(std::random_device{}());
namespace FI
{
    char B[1 << 16], *S = B, *T = B;
    inline char getc()
    {
        return S == T && (T = (S = B) + fread(B, 1, 1 << 16, stdin), S == T) ? EOF : *S++;
    }
    inline void read()
    {
    }

    template <typename Tp, typename... Types>
    inline void read(Tp &o, Types &...Args)
    {
        o = 0;
        bool s = 0;
        char c = getc();
        while (c > '9' || c < '0')
            s |= c == '-', c = getc();
        while (c >= '0' && c <= '9')
            o = o * 10 + c - '0', c = getc();
        if (s)
            o = -o;
        read(Args...);
    }
} // namespace FI
using FI::read;

constexpr int MultiTestCases = 1;
constexpr ll INF = 1e18, threshold = 1e15;

struct Info
{
    ll mx = -INF;
};

Info operator+(const Info &a, const Info &b)
{
    Info res;
    res.mx = std::max(a.mx, b.mx);
    return res;
}

struct Tag
{
    ll delta = 0;
};

struct T
{
    ll delta = 0;
};

T operator+(const T &a, const T &b)
{
    return {a.delta + b.delta};
}

Info operator+(const Info &a, const T &b)
{
    Info res;
    res.mx = a.mx + b.delta;
    return res;
}

void apply(T &a, const Tag &b)
{
    if (b.delta != 0)
        a.delta += b.delta;
}

void apply(Info &a, const Tag &b)
{
    if (b.delta != 0)
        a.mx += b.delta;
}

void apply(Tag &a, const Tag &b)
{
    if (b.delta != 0)
        a.delta += b.delta;
}

template <typename Info, typename Tag, typename Merge = std::plus<Info>>
struct LazySegmentTree
{
    const int n;
    const Merge merge;
    struct node
    {
        Info info;
        Tag tag;
    };
    std::vector<node> tree;
    LazySegmentTree(int _n) : n(_n), merge(Merge()), tree(_n * 4 + 5)
    {
    }
    LazySegmentTree(std::vector<Info> &init, int _n) : LazySegmentTree(_n)
    {
        std::function<void(int, int, int)> build = [&](int p, int l, int r)
        {
            if (l == r)
            {
                tree[p].info = init[l];
                return;
            }
            int mid = (l + r) / 2;
            build(p << 1, l, mid);
            build(p << 1 | 1, mid + 1, r);
            pull(p);
        };
        build(1, 1, n);
    }
    void pull(int p)
    {
        tree[p].info = merge(tree[p << 1].info, tree[p << 1 | 1].info);
    }
    void apply(int p, const Tag &v)
    {
        ::apply(tree[p].info, v);
        ::apply(tree[p].tag, v);
    }
    void push(int p)
    {
        apply(p << 1, tree[p].tag);
        apply(p << 1 | 1, tree[p].tag);
        tree[p].tag = Tag();
    }
    void modify(int p, int l, int r, int x, const Info &v)
    {
        if (l == r)
            return tree[p].info = v, void();
        int mid = (l + r) >> 1;
        push(p);
        if (x <= mid)
            modify(p << 1, l, mid, x, v);
        else
            modify(p << 1 | 1, mid + 1, r, x, v);
        pull(p);
    }
    void modify(int p, const Info &v)
    {
        modify(1, 1, n, p, v);
    }
    Info query(int p, int l, int r, int x, int y)
    {
        if (l == x && r == y)
            return tree[p].info;
        int mid = (l + r) >> 1;
        push(p);
        if (y <= mid)
            return query(p << 1, l, mid, x, y);
        else if (x > mid)
            return query(p << 1 | 1, mid + 1, r, x, y);
        else
            return merge(query(p << 1, l, mid, x, mid), query(p << 1 | 1, mid + 1, r, mid + 1, y));
    }
    Info query(int l, int r)
    {
        return query(1, 1, n, l, r);
    }
    void apply(int p, int l, int r, int x, int y, const Tag &v)
    {
        if (l == x && r == y)
        {
            apply(p, v);
            return;
        }
        int mid = (l + r) >> 1;
        push(p);
        if (y <= mid)
            apply(p << 1, l, mid, x, y, v);
        else if (x > mid)
            apply(p << 1 | 1, mid + 1, r, x, y, v);
        else
            apply(p << 1, l, mid, x, mid, v), apply(p << 1 | 1, mid + 1, r, mid + 1, y, v);
        pull(p);
    }
    void apply(int l, int r, const Tag &v)
    {
        if (l > r)
            return;
        return apply(1, 1, n, l, r, v);
    }
};

int Main()
{
    int n, q;
    read(n, q);
    std::vector<ll> a(n + 1);
    for (int i = 1; i <= n; ++i)
        read(a[i]);
    std::vector fa(n + 1, std::array<int, 11>{});
    std::vector adj(n + 1, std::vector<int>{});
    for (int i = 1; i < n; ++i)
    {
        int u, v;
        read(u, v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    std::vector<int> bfseq{0};
    std::vector bfs_in(n + 1, std::array<std::pair<int, int>, 11>{});
    auto bfs = [&]()
    {
        for (int i = 1; i <= n; ++i)
            bfs_in[i].fill(std::pair{n + 1, 0});
        std::queue<int> q;
        q.push(1);

        while (!q.empty())
        {
            int u = q.front();
            q.pop();
            bfseq.push_back(u);
            if (fa[u][1] != 0)
                adj[u].erase(std::find(adj[u].begin(), adj[u].end(), fa[u][1]));
            for (int v : adj[u])
            {
                fa[v][1] = u;
                for (int d = 2; d <= 10; ++d)
                    fa[v][d] = fa[u][d - 1];
                q.push(v);
            }
        }

        for (int i = 1; i <= n; ++i)
        {
            int u = bfseq[i];
            for (int d = 1; d <= 10; ++d)
            {
                int p = fa[u][d];
                bfs_in[p][d].first = std::min(i, bfs_in[p][d].first);
                bfs_in[p][d].second = std::max(i, bfs_in[p][d].second);
            }
            bfs_in[u][0] = {i, i};
        }
    };

    bfs();

    std::vector<int> in(n + 1), out(n + 1), dfseq{0};
    auto dfs = [&](auto &&self, int u) -> void
    {
        in[u] = dfseq.size();
        dfseq.push_back(u);
        for (int v : adj[u])
            self(self, v);
        out[u] = dfseq.size() - 1;
    };
    dfs(dfs, 1);

    std::vector<Info> init_bfs(n + 1);
    std::vector<Info> init_dfs(n + 1);
    for (int i = 1; i <= n; ++i)
        init_bfs[i] = {a[bfseq[i]]};
    for (int i = 1; i <= n; ++i)
        if (fa[i][10] != 0)
        {
            int u = fa[i][10];
            init_dfs[in[u]] = init_dfs[in[u]] + Info{a[i]};
        }

    LazySegmentTree<Info, Tag> bfs_seg_tree(init_bfs, n);
    LazySegmentTree<T, Tag> tag_seg_tree(n);
    LazySegmentTree<Info, Tag> dfs_seg_tree(init_dfs, n);

    auto update = [&](int l, int r, int v)
    {
        bfs_seg_tree.apply(l, r, {v});
        int p = fa[bfseq[l]][10];
        if (!p)
            return;
        auto [lp, rp] = bfs_in[p][10];
        Info tmp = bfs_seg_tree.query(lp, rp) + tag_seg_tree.query(in[p], in[p]);
        dfs_seg_tree.modify(in[p], tmp);
    };

    auto query = [&](int l, int r)
    {
        Info tmp = bfs_seg_tree.query(l, r);
        int p = fa[bfseq[l]][10];
        if (!p)
            return tmp;
        else
            return tmp + tag_seg_tree.query(in[p], in[p]);
    };

    auto qry1 = [&](int u, int d, int v) -> Info
    {
        int x = u, y = 0;
        Info ans{-INF};
        for (int i = 0; i <= d; ++i, y = x, x = fa[x][1])
        {
            if (!x)
                break;
            auto [l, r] = bfs_in[x][d - i];
            if (!r)
                continue;
            if (!y)
            {
                update(l, r, v);
                ans = ans + query(l, r);
            }
            else if (i < d && y)
            {
                auto [p, q] = bfs_in[y][d - i - 1];
                if (l < p)
                {
                    update(l, p - 1, v);
                    ans = ans + query(l, p - 1);
                }
                if (q < r)
                {
                    update(q + 1, r, v);
                    ans = ans + query(q + 1, r);
                }
            }
        }

        return ans;
    };

    auto qry2 = [&](int u, int d, int v) -> Info
    {
        int x = u, y = 0, cur = d + 1;
        Info ans{-INF};
        for (int i = 0; i <= d; ++i, y = x, x = fa[x][1] ? fa[x][1] : x)
        {
            if ((y != x || d - i < cur))
            {
                auto [l, r] = bfs_in[x][d - i];
                if (l <= r)
                {
                    update(l, r, v);
                    ans = ans + query(l, r);
                    cur = d - i;
                }
            }
            if ((y != x || d - i - 1 < cur) && d - i - 1 >= 0)
            {
                auto [l, r] = bfs_in[x][d - i];
                if (l <= r)
                {
                    update(l, r, v);
                    ans = ans + query(l, r);
                    cur = d - i - 1;
                }
            }
        }
        return ans;
    };

    auto qry3 = [&](int u, int v) -> Info
    {
        Info ans{-INF};
        for (int i = 0; i < 10; ++i)
        {
            auto [l, r] = bfs_in[u][i];
            if (l <= r)
            {
                update(l, r, v);
                ans = ans + query(l, r);
            }
        }
        dfs_seg_tree.apply(in[u], out[u], {v});
        tag_seg_tree.apply(in[u], out[u], {v});
        ans = ans + dfs_seg_tree.query(in[u], out[u]);
        return ans;
    };

    while (q--)
    {
        int op;
        read(op);
        if (op == 3)
        {
            int u, v;
            read(u, v);
            Info res = qry3(u, v);
            if (res.mx < -threshold)
                printf("GG\n");
            else
                printf("%lld\n", res.mx);
            continue;
        }
        int u, v, d;
        read(u, d, v);
        if (op == 1)
        {
            Info res = qry1(u, d, v);
            if (res.mx < -threshold)
                printf("GG\n");
            else
                printf("%lld\n", res.mx);
        }
        else if (op == 2)
        {
            Info res = qry2(u, d, v);
            if (res.mx < -threshold)
                printf("GG\n");
            else
                printf("%lld\n", res.mx);
        }
    }

    return 0;
}

int main()
{
    int TestCases = 1;
    if constexpr (MultiTestCases == 1)
        scanf("%d", &TestCases);

    while (TestCases--)
        Main();
    return 0;
}

详细

Test #1:

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

input:

1
5 5
1 2 1 3 2
1 2
2 3
2 4
4 5
2 2 1 0
1 2 1 3
3 4 -5
2 5 2 3
3 2 -1

output:

3
6
1
5
4

result:

ok 5 lines

Test #2:

score: -100
Wrong Answer
time: 37ms
memory: 3864kb

input:

10000
3 9
42973045452542 34994498886390 -91733395797555
1 3
1 2
1 1 5 -71952967
3 1 -816873082
1 1 5 -842437577
2 3 7 254550528
3 3 -854082700
2 3 2 699808309
3 3 554885567
1 2 7 595565507
1 3 0 -318374053
3 2
-63158159333100 77264362049163 -99188430131116
1 2
3 2
2 2 4 -305866230
3 1 -549738403
3 5...

output:

GG
42972228579460
GG
34994191114364
-91734557652281
34995590730982
-91732603150096
GG
-91732921524149
77264056182933
77263506444530
7065382376488
-61567262981805
-61565691876345
-85115074544128
-85114178052870
96492412785032
-20428913156111
-20428197540063
-14945648679577
-14945981610171
-1494654357...

result:

wrong answer 4th lines differ - expected: '42972483129988', found: '34994191114364'