From 66b06821d0ef0921df2a86834dd135e97852cccd Mon Sep 17 00:00:00 2001 From: Zengtudor Date: Sat, 17 May 2025 11:15:57 +0800 Subject: [PATCH] update --- src/3/T179939.cpp | 67 ++++++++++++++++++++++++ src/3/T459940.cpp | 112 ++++++++++++++++++++++++++++++++++++++++ src/5/17/T294684.cpp | 119 +++++++++++++++++++++++++++++++++++++++++++ src/test.cpp | 4 +- 4 files changed, 300 insertions(+), 2 deletions(-) create mode 100644 src/3/T179939.cpp create mode 100644 src/3/T459940.cpp create mode 100644 src/5/17/T294684.cpp diff --git a/src/3/T179939.cpp b/src/3/T179939.cpp new file mode 100644 index 0000000..d95143d --- /dev/null +++ b/src/3/T179939.cpp @@ -0,0 +1,67 @@ +#include +using namespace std; + +struct SN { + int val; + SN* prev; + SN(int v, SN* p) : val(v), prev(p) {} +}; + +int main() { + ios::sync_with_stdio(false); + cin.tie(0); + + int n; + cin >> n; + vector prt(n + 1); + vector> child(n + 1); + for (int i = 2; i <= n; ++i) { + int p; + cin >> p; + prt[i] = p; + child[p].push_back(i); + } + vector a(n + 1); + for (int i = 1; i <= n; ++i) { + cin >> a[i]; + } + + vector stp(n + 1, nullptr); + vector cnts(n + 1, 0); + + // BFS + queue q; + q.push(1); + stp[1] = new SN(a[1], nullptr); + cnts[1] = 1; + + while (!q.empty()) { + int u = q.front(); + q.pop(); + + for (int v : child[u]) { + SN* ctop = stp[u]; + int ccnt = cnts[u]; + int val = a[v]; + + while (ctop != nullptr && ctop->val <= val) { + SN* temp = ctop; + ctop = ctop->prev; + ccnt--; + } + + ctop = new SN(val, ctop); + ccnt++; + stp[v] = ctop; + cnts[v] = ccnt; + + q.push(v); + } + } + + for (int i = 1; i <= n; ++i) { + cout << cnts[i] << " \n"[i == n]; + } + + return 0; +} \ No newline at end of file diff --git a/src/3/T459940.cpp b/src/3/T459940.cpp new file mode 100644 index 0000000..c3cbd4d --- /dev/null +++ b/src/3/T459940.cpp @@ -0,0 +1,112 @@ +#include +#include +#include +using namespace std; + +const int MAXN = 1e6 + 5; +const int LOG = 20; + +vector adj[MAXN]; +vector euler; +int first[MAXN], depth[MAXN]; +int st_rmq[LOG][MAXN * 2]; +int log_table[MAXN * 2]; +int st_lca[LOG][MAXN]; + +struct State { + int u, parent; + vector::iterator it; +}; + +void iterative_dfs() { + stack st; + st.push({1, -1, adj[1].begin()}); + first[1] = euler.size(); + euler.push_back(1); + depth[1] = 0; + + while (!st.empty()) { + auto& s = st.top(); + if (s.it == adj[s.u].end()) { + st.pop(); + if (s.parent != -1) { + euler.push_back(s.parent); + } + } else { + int v = *s.it; + s.it++; + if (v == s.parent) continue; + first[v] = euler.size(); + euler.push_back(v); + depth[v] = depth[s.u] + 1; + st.push({v, s.u, adj[v].begin()}); + } + } +} + +void build_rmq() { + int m = euler.size(); + log_table[1] = 0; + for (int i = 2; i <= m; ++i) + log_table[i] = log_table[i/2] + 1; + for (int i = 0; i < m; ++i) + st_rmq[0][i] = i; + for (int k = 1; (1 << k) <= m; ++k) { + for (int i = 0; i + (1 << k) <= m; ++i) { + int a = st_rmq[k-1][i]; + int b = st_rmq[k-1][i + (1 << (k-1))]; + st_rmq[k][i] = (depth[euler[a]] < depth[euler[b]] ? a : b); + } + } +} + +int lca(int u, int v) { + int l = first[u], r = first[v]; + if (l > r) swap(l, r); + int k = log_table[r - l + 1]; + int a = st_rmq[k][l]; + int b = st_rmq[k][r - (1 << k) + 1]; + return euler[depth[euler[a]] < depth[euler[b]] ? a : b]; +} + +void build_lca_st(int n) { + for (int i = 1; i <= n; ++i) + st_lca[0][i] = i; + for (int k = 1; (1 << k) <= n; ++k) { + for (int i = 1; i + (1 << k) - 1 <= n; ++i) { + int a = st_lca[k-1][i]; + int b = st_lca[k-1][i + (1 << (k-1))]; + st_lca[k][i] = lca(a, b); + } + } +} + +int query(int l, int r) { + if (l == r) return l; + int len = r - l + 1; + int k = log_table[len]; + int a = st_lca[k][l]; + int b = st_lca[k][r - (1 << k) + 1]; + return lca(a, b); +} + +int main() { + iostream::sync_with_stdio(false),cin.tie(nullptr); + int n, q; + cin>>n>>q; + for (int i = 1; i < n; ++i) { + int u, v; + cin>>u>>v; + adj[u].push_back(v); + adj[v].push_back(u); + } + iterative_dfs(); + build_rmq(); + build_lca_st(n); + while (q--) { + int l, r; + cin>>l>>r; + cout< +using namespace std; + +const int N = 1e5 + 10; + +struct Node { + int l, r; + int max_len, prefix, suffix; + int tag; // -1 无覆盖 | 0 or 1覆盖 +} tr[N << 2]; + +struct Info { + int max_len, prefix, suffix, total; +}; + +void push_up(int u) { + Node &left = tr[u << 1]; + Node &right = tr[u << 1 | 1]; + tr[u].prefix = left.prefix; + if (left.prefix == left.r - left.l + 1) { + tr[u].prefix += right.prefix; + } + tr[u].suffix = right.suffix; + if (right.suffix == right.r - right.l + 1) { + tr[u].suffix += left.suffix; + } + tr[u].max_len = max({left.max_len, right.max_len, left.suffix + right.prefix}); +} + +void push_down(int u) { + if (tr[u].tag != -1) { + int tag = tr[u].tag; + int lson = u << 1, rson = u << 1 | 1; + tr[lson].max_len = tr[lson].prefix = tr[lson].suffix = tag ? (tr[lson].r - tr[lson].l + 1) : 0; + tr[lson].tag = tag; + tr[rson].max_len = tr[rson].prefix = tr[rson].suffix = tag ? (tr[rson].r - tr[rson].l + 1) : 0; + tr[rson].tag = tag; + tr[u].tag = -1; + } +} + +void build(int u, int l, int r, const string &s) { + tr[u].l = l; + tr[u].r = r; + tr[u].tag = -1; + if (l == r) { + int val = s[l - 1] - '0'; + tr[u].max_len = tr[u].prefix = tr[u].suffix = val; + return; + } + int mid = (l + r) >> 1; + build(u << 1, l, mid, s); + build(u << 1 | 1, mid + 1, r, s); + push_up(u); +} + +void update(int u, int l, int r, int x) { + if (tr[u].l >= l && tr[u].r <= r) { + tr[u].max_len = tr[u].prefix = tr[u].suffix = x ? (tr[u].r - tr[u].l + 1) : 0; + tr[u].tag = x; + return; + } + push_down(u); + int mid = (tr[u].l + tr[u].r) >> 1; + if (l <= mid) update(u << 1, l, r, x); + if (r > mid) update(u << 1 | 1, l, r, x); + push_up(u); +} + +Info query(int u, int ql, int qr) { + if (tr[u].r < ql || tr[u].l > qr) { + return {0, 0, 0, 0}; + } + if (ql <= tr[u].l && tr[u].r <= qr) { + return {tr[u].max_len, tr[u].prefix, tr[u].suffix, tr[u].r - tr[u].l + 1}; + } + push_down(u); + Info left = query(u << 1, ql, qr); + Info right = query(u << 1 | 1, ql, qr); + if (left.total == 0) return right; + if (right.total == 0) return left; + Info res; + res.prefix = left.prefix; + if (left.prefix == left.total) { + res.prefix += right.prefix; + } + res.suffix = right.suffix; + if (right.suffix == right.total) { + res.suffix += left.suffix; + } + res.max_len = max({left.max_len, right.max_len, left.suffix + right.prefix}); + res.total = left.total + right.total; + return res; +} + +int main() { + ios::sync_with_stdio(false); + cin.tie(nullptr); + int n, q; + cin >> n >> q; + string s; + cin >> s; + build(1, 1, n, s); + while (q--) { + int op; + cin >> op; + if (op == 1) { + int l, r, x; + cin >> l >> r >> x; + update(1, l, r, x); + } else { + int l, r; + cin >> l >> r; + Info info = query(1, l, r); + cout << info.max_len << '\n'; + } + } + return 0; +} \ No newline at end of file diff --git a/src/test.cpp b/src/test.cpp index 394e26d..7925ad2 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -24,8 +24,8 @@ void dfs(int u, int parent) { for (int v : tree[u].children) { if (v == parent) continue; - long long option = dp[u][1] - dp[v][0] + dp[v][1] - b; - dp[u][1] = max(dp[u][1], option); + // long long option = dp[u][1] - dp[v][0] + dp[v][1] - b; + // dp[u][1] = max(dp[u][1], option); } }