噢这该死的再见2023比赛,我的代码无法通过
查看原帖
噢这该死的再见2023比赛,我的代码无法通过
362750
TernaryTree楼主2023/12/31 19:35

有人知道我如何使这个严格的O(nlogn)代码通过吗?不幸地,我的测试用例35超过了时间限制。噢,帮帮我这个倒霉蛋吧!

// LUOGU_RID: 141571843
#pragma GCC optimize(3)
#pragma GCC target("avx")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define ll long long
#define ls (u << 1)
#define rs (u << 1 | 1)
#define mid ((l + r) >> 1)
#define lc ls, l, mid
#define rc rs, mid + 1, r
#define rt 1, 1, n

using namespace std;

struct ios {
    inline char read() {
        static const int inlen = 1 << 18 | 1;
        static char buf[inlen], *s, *t;
        return (s == t) && (t = (s = buf) + fread(buf, 1, inlen, stdin)), s == t ? -1 : *s++;
    }
    template<typename T> inline ios& operator>> (T &x) {
        static char c11, boo;
        for (c11 = read(), boo = 0; !isdigit(c11); c11 = read()) {
            if (c11 == -1) return *this;
            boo |= c11 == '-';
        }
        for (x = 0; isdigit(c11); c11 = read()) x = x * 10 + (c11 ^ '0');
        boo && (x = -x);
        return *this;
    }
} fin;

struct exios {
    template<typename _CharT, typename _Traits = char_traits<_CharT>>
    struct typ {
        typedef basic_ostream<_CharT, _Traits>& (* end) (basic_ostream<_CharT, _Traits>&);
    };

    template<typename T> friend exios &operator<<(exios &out, T num) {
        if (num < 0) putchar('-'), num = -num;
        if (num >= 10) out << num / 10;
        putchar(num % 10 + '0');
        return out;
    }

    friend exios &operator<<(exios &out, const char * s) { printf("%s", s); return out; }
    friend exios &operator<<(exios &out, string s) { cout << s; return out; }
    friend exios &operator<<(exios &out, typ<char>::end e) { puts(""); return out; }
} fout;

const int maxn = 6e5 + 10;

struct node {
	int mx, add;
	node() = default;
	node(int mx): mx(mx) {}
};

int T, n;
ll ans;
int fa[maxn], a[maxn];
int bk[maxn], lst[maxn];
int dfn[maxn], idx, siz[maxn];
vector<int> g[maxn];
vector<int> p[maxn];
node tr[maxn << 2];

void clear() {
	for (int i = 0; i <= n; i++) fa[i] = a[i] = bk[i] = lst[i] = dfn[i] = siz[i] = 0, g[i].clear(), p[i].clear();
	n = idx = ans = 0;
}

void build(int u, int l, int r) {
	tr[u] = node();
	if (l == r) return;
	build(lc), build(rc);
	tr[u].mx = tr[ls].mx < tr[rs].mx ? tr[rs].mx : tr[ls].mx;
}

void pushdown(int u) {
	tr[ls].mx += tr[u].add;
	tr[ls].add += tr[u].add;
	tr[rs].mx += tr[u].add;
	tr[rs].add += tr[u].add;
	tr[u].add = 0;
}

void add(int u, int l, int r, int ql, int qr, int k) {
	if (ql <= l && r <= qr) {
		tr[u].mx += k;
		tr[u].add += k;
		return;
	}
	pushdown(u);
	if (ql <= mid) add(lc, ql, qr, k);
	if (qr > mid) add(rc, ql, qr, k);
	tr[u].mx = tr[ls].mx < tr[rs].mx ? tr[rs].mx : tr[ls].mx;
} 

int query(int u, int l, int r, int ql, int qr) {
	if (ql <= l && r <= qr) return tr[u].mx;
	pushdown(u);
	int y = 0;
	if (ql <= mid) y = max(y, query(lc, ql, qr));
	if (qr > mid) y = max(y, query(rc, ql, qr));
	tr[u].mx = tr[ls].mx < tr[rs].mx ? tr[rs].mx : tr[ls].mx;
	return y;
}

void dfs1(int u) {
	dfn[u] = ++idx, siz[u] = 1;
	p[lst[u] = bk[a[u]]].push_back(u);
	int l = bk[a[u]];
	bk[a[u]] = u;
	for (int v : g[u]) dfs1(v), siz[u] += siz[v];
	bk[a[u]] = l;
}

void dfs2(int u, int fa) {
	for (int y : p[fa]) add(rt, dfn[y], dfn[y] + siz[y] - 1, 1);
	int mx = 1, sc = 1;
	int q = fa ? query(rt, dfn[fa], dfn[fa]) : 0;
	for (int v : g[u]) {
		int y = query(rt, dfn[v], dfn[v] + siz[v] - 1) - q;
		if (y > mx) sc = mx, mx = y;
		else if (y > sc) sc = y;
	}
	for (int v : g[u]) dfs2(v, u);
	if ((ll) mx * sc > ans) ans = (ll) mx * sc;
	for (int y : p[fa]) add(rt, dfn[y], dfn[y] + siz[y] - 1, -1);
}

signed main() {
	fin >> T;
	while (T--) {
		fin >> n;
		for (int i = 2; i <= n; i++) fin >> fa[i], g[fa[i]].push_back(i); 
		for (int i = 1; i <= n; i++) fin >> a[i]; 
		build(rt);
		dfs1(1); 
		dfs2(1, 0);
		fout << ans << endl;
		if (T) clear();
	}
	return 0;
}

2023/12/31 19:35
加载中...