QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#142253#4408. 燃烧的呐球NOI_AK_ME100 ✓3123ms426020kbC++2016.0kb2023-08-18 20:23:502023-08-18 20:23:51

Judging History

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

  • [2023-08-18 20:23:51]
  • 评测
  • 测评结果:100
  • 用时:3123ms
  • 内存:426020kb
  • [2023-08-18 20:23:50]
  • 提交

answer

#include <bits/stdc++.h>
const int MAXN = 1e6 + 10;
const int MAXM = 3e5 + 10;
namespace trash_without_mode
{
#define foe(i, now) for (int i = head[now]; ~i; i = edg[i].edg)
#define fo(i, g1, g2) for (int i = (g1), __Endi__ = (g2); i <= __Endi__; ++i)
#define fd(i, g1, g2) for (int i = (g1), __Endi__ = (g2); i >= __Endi__; --i)
#define go(v, now) for (auto &v : edg[now])
#define mem(g1, g2) memset((g1), g2, sizeof((g1)))
#define lowbit(now) ((now) & (-now))
#define mid ((l + r) / 2)
#define ll long long
#define pb push_back
#define mp(g1, g2) make_pair((g1), (g2))
#define PII pair<int, int>
#define pow2(g2) (1ll << (g2))
#define II inline void
#define INF (5e6)
#define ps push
#define lsond lson, l, mid
#define rsond rson, mid + 1, r

    namespace Fread
    {
        const int SIZE = (1 << 26) + 1; // namespace Fread
        char buf[SIZE], *S, *T;
    }
    namespace Fwrite
    {
        const int SIZE = (1 << 26) + 1; // namespace Fwrite
        char buf[SIZE], *S = buf, *T = buf + SIZE;
        inline void flush()
        {
            fwrite(buf, 1, S - buf, stdout), S = buf;
        }
        struct NTR
        {
            ~NTR()
            {
                flush();
            }
        } ztr;
    }

#ifdef ONLINE_JUDGE
#define getchar() (Fread::S == Fread::T && (Fread::T = (Fread::S = Fread::buf) + fread(Fread::buf, 1, 1 << 23, stdin), Fread::S == Fread::T) ? '\n' : *Fread::S++)
#define putchar(c) (*Fwrite::S++ = c, (Fwrite::S != Fwrite::T) ? 0 : (Fwrite::flush(), 0))
#endif
    namespace Fastio
    {
        struct Reader
        {
            template <typename T>
            inline Reader &operator>>(T &now)
            {
                static char c;
                static short f;
                c = getchar(), f = 1;

                while (!isdigit(c))
                {
                    c ^ '-' ? c = getchar() : (f = -1, c = getchar());
                }
                now = 0;

                while (isdigit(c))
                {
                    now = now * 10 + (c ^ '0'), c = getchar();
                }
                return now *= f, *this;
            }
            inline Reader &operator>>(char &c)
            {
                c = getchar();

                while (c == '\n' || c == ' ')
                    c = getchar();

                return *this;
            }
            inline Reader &operator>>(char *str)
            {
                static int len = 0;
                len = 0;
                static char c;
                c = getchar();

                while (c == '\n' || c == ' ')
                    c = getchar();

                while (c ^ '\n' && c ^ ' ')
                {
                    str[len++] = c, c = getchar();
                }
                return str[len] = '\0', *this;
            }
            Reader() {}

        } cin;
        const char endl = '\n';
        struct Writer
        {
            template <typename T>
            inline Writer &operator<<(T now)
            {
                static int cnt = 0;
                now ? (now < 0 ? putchar('-'), now = -now, cnt = 0 : cnt = 0) : (putchar('0'), cnt = 0);
                static int sta[45];

                while (now)
                {
                    sta[++cnt] = now % 10, now /= 10;
                }
                while (cnt)
                {
                    putchar(sta[cnt] | 48), --cnt;
                }
                return *this;
            }
            inline Writer &operator<<(const char c)
            {
                return putchar(c), *this;
            }
            inline Writer &operator<<(const char *str)
            {
                static int cur = 0;
                cur = 0;

                while (str[cur])
                    putchar(str[cur++]);

                return *this;
            }
            inline Writer &operator<<(char *str)
            {
                static int cur = 0;
                cur = 0;

                while (str[cur])
                    putchar(str[cur++]);

                return *this;
            }
            Writer() {}

        } cout;
    }

#define cin Fastio ::cin
#define cout Fastio ::cout
#define endl Fastio ::endl

    using namespace std;
}
using namespace trash_without_mode;
int n, m;
int fa[MAXM];
vector<int> edg[MAXM];
int siz[MAXM];
PII a[MAXM];
int L[MAXM], R[MAXM], *dfn = L;
vector <int> nodex[MAXM],nodey[MAXM];
namespace Init
{
    int dfnclock = 0;
    void dfs(int x)
    {
        L[x] = ++dfnclock;
        for (auto v : edg[x])
            dfs(v);
        R[x] = dfnclock;
    }
    int cnt = 0;
    void init()
    {
        vector <int> siz2(MAXN),newid(MAXN),fa2(MAXN),vis(MAXN);
        cin >> n >> m;
        fo(i, 2, n) cin >> fa2[i];
        siz2[1] = 1;
        fd(i, n, 2) siz2[i] += 1, siz2[fa2[i]] += siz2[i];
        vis[1] = 1;
        fo(i, 1, m) cin >> a[i].first >> a[i].second, vis[a[i].first] = vis[a[i].second] = 1;
        fo(i, 2, n)
        {
            if (!vis[fa2[i]])
                fa2[i] = fa2[fa2[i]];
        }
        fo(i, 1, n) if (vis[i]) newid[i] = ++cnt;
        siz[1] = siz2[1];
        fo(i, 2, n) if (newid[i]) fa[newid[i]] = newid[fa2[i]], siz[newid[i]] = siz2[i];
        fo(i, 1, m) a[i].first = newid[a[i].first], a[i].second = newid[a[i].second];
        n = cnt;
        fo(i, 2, n) edg[fa[i]].emplace_back(i);
        dfs(1);
        fo(i,1,m) nodex[a[i].first].emplace_back(i);
        fo(i,1,m) nodey[a[i].second].emplace_back(i);
    }
}
struct DSU
{
    int fa[MAXN];
    void init(int n) { iota(fa + 1, fa + 1 + n, 1); }
    int findfa(int x) { return (fa[x] ^ x) ? fa[x] = findfa(fa[x]) : x; }
    bool merge(int x, int y)
    {
        x = findfa(x), y = findfa(y);
        if (x == y)
            return 0;
        fa[x] = y;
        return 1;
    }
    int operator[](int x) { return findfa(x); }
} col;
struct Edge
{
    PII f, s;
    Edge(PII a = mp(8e6, 0), PII b = mp(5e6, 0)) : f(a), s(b) {}
    friend Edge operator+(Edge a, Edge b)
    {
        if (a.f > b.f)
        {
            if (col[a.f.second] == col[b.f.second]) b.s = min(b.s,a.s);
            else b.s = min(b.s,a.f);
            return b;
        }else
        {
            if (col[a.f.second] == col[b.f.second]) a.s = min(a.s,b.s);else
            a.s = min(a.s,b.f);
            return a;
        }
    }
    void operator+=(PII b)
    {
        if (col[b.second] == col[f.second]) {f.first = min(f.first,b.first);return ;}
        if (f > b) s = f,f = b;else s = min(s,b);
        return ;
    }
    friend Edge operator+(Edge a, PII b)
    {
        if (col[b.second] == col[a.f.second]) {a.f.first = min(a.f.first,b.first);return a;}
        if (a.f > b) a.s = a.f,a.f = b;else a.s = min(a.s,b);
        return a;
    }
    friend bool operator!=(Edge a, Edge b)
    {
        return (a.f != b.f) || (a.s != b.s);
    }
    friend bool operator==(Edge a, Edge b)
    {
        return (a.f == b.f) && (a.s == b.s);
    }
};
Edge t[MAXM * 60];
int ch[MAXM * 60][2];
int root[MAXN];
PII ans[MAXM];
int cnt = 0;
#define lson ch[x][0]
#define rson ch[x][1]
int qwq = 0;
PII res;
// 1 xi,yi均为祖先
void init_12()
{
    fo (i,0,cnt) t[i] = Edge(), ch[i][0] = ch[i][1] = 0;
    cnt = 0;
    mem(root, 0);
}
void modify_1(int &x, int l, int r, int pos, const PII val)
{
    if (!x)
        x = ++cnt;
    if (l == r)
    {
        t[x] += val;
        return;
    }
    if (pos <= mid)
        modify_1(lsond, pos, val);
    if (mid < pos)
        modify_1(rsond, pos, val);
    t[x] = t[lson] + t[rson];
    return;
}
Edge query_1(int &x, int l, int r, int L, int R)
{
    if (!x)
        return Edge();
    if (L <= l && r <= R)
        return t[x];
    if (R <= mid)
        return query_1(lsond, L, R);
    if (mid < L)
        return query_1(rsond, L, R);
    return query_1(lsond, L, R) + query_1(rsond, L, R);
}
int merge_1(int x, int y, int l, int r)
{
    if (!x || !y)
        return x | y;
    if (l == r)
    {
        t[x] = t[x] + t[y];
        return x;
    }
    lson = merge_1(lson, ch[y][0], l, mid);
    rson = merge_1(rson, ch[y][1], mid + 1, r);
    t[x] = t[lson] + t[rson];
    return x;
}
// 2 xi为祖先 yi为孩子
void modify_2(int &x, int l, int r, int L, int R, const PII val)
{
    if (!x)
        x = ++cnt;
    if (L <= l && r <= R)
        return (void)(t[x] += val);
    if (L <= mid)
        modify_2(lsond, L, R, val);
    if (mid < R)
        modify_2(rsond, L, R, val);
}
void query_2(int x, int l, int r, int pos)
{
    if (!x) return ;
    if (col[qwq] == col[t[x].f.second]) res = min(res,t[x].s);else
        res = min(res,t[x].f);
    if (l == r) return ;
    if (pos <= mid) query_2(lsond, pos);
    if (mid < pos) query_2(rsond, pos);
    return ;
}
int merge_2(int x, int y)
{
    if (!x || !y)
        return x | y;
    t[x] = t[x] + t[y];
    lson = merge_2(lson, ch[y][0]);
    rson = merge_2(rson, ch[y][1]);
    return x;
}
#undef lson
#undef rson
#define lson ((x) << 1)
#define rson (lson | 1)
stack<pair<PII, Edge>> opt;
void build(int x, int l, int r)
{
    t[x] = Edge();
    if (l == r)
        return;
    build(lsond);
    build(rsond);
}
void init_34()
{
    stack<pair<PII, Edge>> orz;
    swap(opt, orz);
    build(1, 1, n);
}
void roll(int x)
{
    while (!opt.empty() && opt.top().first.second == x)
    {
        t[opt.top().first.first] = opt.top().second;
        opt.pop();
    }
    return;
}
// xi 为孩子,yi 为祖先。
int tim = 0;
void modify_3(int x, int l, int r, int pos, const PII val)
{
    if (l == r)
        return (void)(opt.push(mp(mp(x, tim), t[x])), t[x] = t[x] + val);
    Edge orz = t[x];
    if (pos <= mid)
        modify_3(lsond, pos, val);
    if (mid < pos)
        modify_3(rsond, pos, val);
    t[x] = t[lson] + t[rson];
    if (t[x] != orz)
        opt.push(mp(mp(x, tim), orz));
}
Edge query_3(int x, int l, int r, int L, int R)
{
    if (t[x] == Edge())
        return Edge();
    if (L <= l && r <= R)
        return t[x];
    if (R <= mid)
        return query_3(lsond, L, R);
    if (mid < L)
        return query_3(rsond, L, R);
    return query_3(lsond, L, R) + query_3(rsond, L, R);
}
void modify_4(int x, int l, int r, int L, int R, const PII val)
{
    if (L <= l && r <= R)
        return (void)(opt.push(mp(mp(x, tim), t[x])), t[x] = t[x] + val);
    if (L <= mid)
        modify_4(lsond, L, R, val);
    if (mid < R)
        modify_4(rsond, L, R, val);
    return;
}
Edge query_4(int x, int l, int r, int pos)
{
    if (l == r) return t[x];
    if (pos <= mid)
        return t[x] + query_4(lsond, pos);
    if (mid < pos)
        return t[x] + query_4(rsond, pos);
    return Edge();
}
void dfs1()
{
    fd (x,n,1)
    {
        for (auto v:nodex[x]) 
        modify_1(root[x],1,n,dfn[a[v].second],mp(-siz[a[v].first] - siz[a[v].second],v));
        for (auto v:nodex[x]) 
        {
            Edge res = query_1(root[x],1,n,L[a[v].second],R[a[v].second]);
            res.f.first += siz[a[v].first] + siz[a[v].second];
            res.s.first += siz[a[v].first] + siz[a[v].second];
            if (col[res.f.second] == col[v]) ans[v] = min(ans[v],res.s);
            else ans[v] = min(ans[v],res.f);
        }
        if (fa[x])
        root[fa[x]] = merge_1(root[fa[x]],root[x],1,n);
    }
}
void dfs2()
{
    fd (x,n,1)
    {
        for (auto v:nodex[x]) 
        modify_2(root[x],1,n,L[a[v].second],R[a[v].second],mp(-siz[a[v].first] + siz[a[v].second],v));
        for (auto v:nodex[x]) 
        {
            qwq = v;
            res = mp(8e6,0);
            query_2(root[x],1,n,dfn[a[v].second]);
            res.first += siz[a[v].first] - siz[a[v].second];
            ans[v] = min(ans[v],res);
        }
        if (fa[x])
        root[fa[x]] = merge_2(root[fa[x]],root[x]);
    }
}
void dfs3()
{
    fd (x,n,1)
    {
        for (auto v:nodey[x]) 
        modify_2(root[x],1,n,L[a[v].first],R[a[v].first],mp(-siz[a[v].second] + siz[a[v].first],v));
        for (auto v:nodey[x]) 
        {
            qwq = v;
            res = mp(8e6,0);
            query_2(root[x],1,n,dfn[a[v].first]);
            res.first += siz[a[v].second] - siz[a[v].first];
            ans[v] = min(ans[v],res);
        }
        if (fa[x])
        root[fa[x]] = merge_2(root[fa[x]],root[x]);
    }
}
void dfs4(int x)
{
    tim = x;
    for (auto v:nodex[x]) 
    modify_4(1,1,n,L[a[v].second],R[a[v].second],mp(siz[a[v].first] + siz[a[v].second],v));
    for (auto v:edg[x]) 
    {
        dfs4(v);
    }
    for (auto v:nodex[x]) 
    {
        Edge res = query_4(1,1,n,dfn[a[v].second]);
        res.f.first += -siz[a[v].first] - siz[a[v].second];
        res.s.first += -siz[a[v].first] - siz[a[v].second];
        if (col[res.f.second] == col[v]) ans[v] = min(ans[v],res.s);
        else ans[v] = min(ans[v],res.f);
    }
    roll(x);
}
Edge minn,minnsonx,minnfax,minnsony,minnfay;
pair<Edge,Edge> dfs5(int x)
{
    Edge my = minnfay,mx = minnfax;
    Edge sumx,sumy;
    for (auto v:nodex[x]) 
    sumx = sumx + mp(-siz[a[v].first] + siz[a[v].second],v);
    for (auto v:nodey[x]) 
    sumy = sumy + mp(siz[a[v].first] - siz[a[v].second],v);
    for (auto v:nodey[x]) 
    minnfay = minnfay + mp(siz[a[v].first] + siz[a[v].second],v);
    for (auto v:nodex[x]) 
    minnfax = minnfax + mp(siz[a[v].first] + siz[a[v].second],v);
    for (auto v:edg[x])
    {
        pair<Edge,Edge> qwq = dfs5(v);
        sumx = sumx + qwq.first,sumy = sumy + qwq.second;
    }
    
    for (auto v:nodex[x]) 
    {
        if (col[v] == col[minnfax.f.second]) 
        ans[v] = min(ans[v],mp(minnfax.s.first - siz[a[v].first] + siz[a[v].second],minnfax.s.second));
        else 
        ans[v] = min(ans[v],mp(minnfax.f.first - siz[a[v].first] + siz[a[v].second],minnfax.f.second));
    }
    for (auto v:nodey[x]) 
    {
        if (col[v] == col[minnfay.f.second]) 
        ans[v] = 
        min(ans[v],mp(minnfay.s.first + siz[a[v].first] - siz[a[v].second],minnfay.s.second));
        else ans[v] = 
        min(ans[v],mp(minnfay.f.first + siz[a[v].first] - siz[a[v].second],minnfay.f.second));
    }
    
    
    for (auto v:nodex[x]) 
    {
        if (col[v] == col[sumx.f.second]) 
        ans[v] = min(ans[v],mp(sumx.s.first + siz[a[v].first] + siz[a[v].second],sumx.s.second));
        else ans[v] = min(ans[v],mp(sumx.f.first + siz[a[v].first] + siz[a[v].second],sumx.f.second));
    }
    for (auto v:nodey[x]) 
    {
        if (col[v] == col[sumy.f.second]) 
        ans[v] = min(ans[v],mp(sumy.s.first + siz[a[v].first] + siz[a[v].second],sumy.s.second));
        else ans[v] = min(ans[v],mp(sumy.f.first + siz[a[v].first] + siz[a[v].second],sumy.f.second));
    }
    minnfay = my,minnfax = mx;
    return mp(sumx,sumy);
}
signed main()
{
#ifndef ONLINE_JUDGE
    freopen("txt.in", "r", stdin);
    freopen("txt.out", "w", stdout);
#endif
    Init::init();
    col.init(m);
    __int128 res = 0;
    vector <int> S;
    while (1)
    {
        bitset<MAXM> vis;
        S.clear();
        fo (i, 1, m) if (!vis[col[i]]) vis.set(col[i]), S.emplace_back(col[i]);
        if (S.size() == 1)   break;
        minnsonx = minnsony = minn = minnfax = minnfay = Edge();
        fo (i,1,m) minn = minn + mp(siz[a[i].first] + siz[a[i].second],i);
        fo (i,1,m) 
        {
            if (col[i] == col[minn.f.second]) ans[i] = minn.s;
            else ans[i] = minn.f;
            ans[i].first += siz[a[i].first] + siz[a[i].second];
        }
        init_12(),dfs1(),init_12(),dfs2(),init_12(),dfs3();
        init_34();
        dfs4(1);
        dfs5(1);
        fo (i,1,m) ans[col[i]] = min(ans[col[i]],ans[i]);
        vector <int> qwq;
        fo (i,1,m) if (col[i] == i) qwq.emplace_back(i);
        for (auto v:qwq)
        res += col.merge(v,ans[v].second) * ans[v].first;
    }   
    cout << res;
    return 0;
}

Details

Subtask #1:

score: 10
Accepted

Test #1:

score: 10
Accepted
time: 23ms
memory: 328152kb

Test #2:

score: 0
Accepted
time: 15ms
memory: 324932kb

Test #3:

score: 0
Accepted
time: 12ms
memory: 325408kb

Test #4:

score: 0
Accepted
time: 28ms
memory: 328648kb

Test #5:

score: 0
Accepted
time: 16ms
memory: 325852kb

Subtask #2:

score: 10
Accepted

Dependency #1:

100%
Accepted

Test #6:

score: 10
Accepted
time: 314ms
memory: 334576kb

Test #7:

score: 0
Accepted
time: 150ms
memory: 334460kb

Test #8:

score: 0
Accepted
time: 129ms
memory: 331484kb

Test #9:

score: 0
Accepted
time: 145ms
memory: 332292kb

Test #10:

score: 0
Accepted
time: 129ms
memory: 334480kb

Subtask #3:

score: 10
Accepted

Dependency #2:

100%
Accepted

Test #11:

score: 10
Accepted
time: 1056ms
memory: 339180kb

Test #12:

score: 0
Accepted
time: 635ms
memory: 340204kb

Test #13:

score: 0
Accepted
time: 495ms
memory: 335864kb

Test #14:

score: 0
Accepted
time: 488ms
memory: 338348kb

Test #15:

score: 0
Accepted
time: 561ms
memory: 337892kb

Subtask #4:

score: 20
Accepted

Test #16:

score: 20
Accepted
time: 332ms
memory: 327884kb

Test #17:

score: 0
Accepted
time: 399ms
memory: 330676kb

Test #18:

score: 0
Accepted
time: 228ms
memory: 328312kb

Test #19:

score: 0
Accepted
time: 300ms
memory: 328044kb

Test #20:

score: 0
Accepted
time: 310ms
memory: 330968kb

Subtask #5:

score: 10
Accepted

Test #21:

score: 10
Accepted
time: 2940ms
memory: 423092kb

Test #22:

score: 0
Accepted
time: 2956ms
memory: 422428kb

Test #23:

score: 0
Accepted
time: 3003ms
memory: 426020kb

Test #24:

score: 0
Accepted
time: 3028ms
memory: 422444kb

Test #25:

score: 0
Accepted
time: 3123ms
memory: 422900kb

Subtask #6:

score: 10
Accepted

Test #26:

score: 10
Accepted
time: 1033ms
memory: 343932kb

Test #27:

score: 0
Accepted
time: 1017ms
memory: 341700kb

Test #28:

score: 0
Accepted
time: 1031ms
memory: 343396kb

Test #29:

score: 0
Accepted
time: 1030ms
memory: 342660kb

Test #30:

score: 0
Accepted
time: 1052ms
memory: 344924kb

Subtask #7:

score: 30
Accepted

Dependency #1:

100%
Accepted

Dependency #2:

100%
Accepted

Dependency #3:

100%
Accepted

Dependency #4:

100%
Accepted

Dependency #5:

100%
Accepted

Dependency #6:

100%
Accepted

Test #31:

score: 30
Accepted
time: 2442ms
memory: 353148kb

Test #32:

score: 0
Accepted
time: 1499ms
memory: 349036kb

Test #33:

score: 0
Accepted
time: 1187ms
memory: 344732kb

Test #34:

score: 0
Accepted
time: 1082ms
memory: 348224kb

Test #35:

score: 0
Accepted
time: 1291ms
memory: 348140kb

Test #36:

score: 0
Accepted
time: 2392ms
memory: 350620kb

Test #37:

score: 0
Accepted
time: 1406ms
memory: 352224kb

Test #38:

score: 0
Accepted
time: 1083ms
memory: 344520kb

Test #39:

score: 0
Accepted
time: 1103ms
memory: 348688kb

Test #40:

score: 0
Accepted
time: 1383ms
memory: 351436kb