QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#142253 | #4408. 燃烧的呐球 | NOI_AK_ME | 100 ✓ | 3123ms | 426020kb | C++20 | 16.0kb | 2023-08-18 20:23:50 | 2023-08-18 20:23:51 |
Judging History
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