2024.1.7做题纪要
P4093 [HEOI2016/TJOI2016] 序列
不会写,褐的题解。
设
教员
#include <bits/stdc++.h> int N, M; int number[110000], min[110000], max[110000]; class Binary_Indexed_Tree { #define lowbit(x) (x & (-x)) public: int num[110000]; Binary_Indexed_Tree() { for (int i = 1; i <= 100000; ++ i) num[i] = -1e9; } void Add(int position, int val) { while (position <= 1e5) { num[position] = std::max(num[position], val); position += lowbit(position); } } int Query(int position) { int result = -1e9; while (position) { result = std::max(result, num[position]); position -= lowbit(position); } return result; } void clear(int position) { while (position <= 1e5) { num[position] = -1e9; position += lowbit(position); } } }tree; int dp[110000], p[110000]; bool cmp1(int &i, int &j) { return max[i] < max[j]; } bool cmp2(int &i, int &j) { return number[i] < number[j]; } void CDQ(int l, int r) { if (l == r) { dp[l] = std::max(dp[l], 1); return; } int mid = (l + r) >> 1; CDQ(l, mid); for (int i = l; i <= r; ++ i) p[i] = i; std::sort(p + l, p + mid + 1, cmp1); std::sort(p + mid + 1, p + r + 1, cmp2); for (int i = l, j = mid + 1; j <= r; ++j) { while (i <= mid && max[p[i]] <= number[p[j]]) { tree.Add(number[p[i]], dp[p[i]]); ++i; } dp[p[j]] = std::max(dp[p[j]], tree.Query(min[p[j]]) + 1); } for (int i = l; i <= mid; ++ i) tree.clear(number[i]); CDQ(mid + 1, r); } int answer; int main() { std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0); std::cin >> N >> M; for (int i = 1; i <= N; ++ i) { std::cin >> number[i]; max[i] = min[i] = number[i]; } for (int i = 1, x, y; i <= M; ++ i) { std::cin >> x >> y; min[x] = std::min(min[x], y); max[x] = std::max(max[x], y); } CDQ(1, N); for (int i = 1; i <= N; ++ i) answer = std::max(answer, dp[i]); std::cout << answer << '\n'; return 0; } /* */
P3345 [ZJOI2015] 幻想乡战略游戏
毒瘤题。
看见度数小于
小胡子
#include <bits/stdc++.h> typedef long long ll; ll N, Q; bool visit[210000]; ll cnt = 1, head[210000], next[210000], to[210000], value[210000]; ll size[210000], root, max[210000], S; void AddEdge(ll u, ll v, ll val) { ++ cnt; next[cnt] = head[u]; head[u] = cnt; to[cnt] = v; value[cnt] = val; } ll fa[110000]; ll len[110000]; void GetRoot(ll now, ll fat) { size[now] = 1; max[now] = 0; for (ll i = head[now]; i; i = next[i]) { if (visit[to[i]] || fat == to[i]) continue; GetRoot(to[i], now); size[now] += size[to[i]]; max[now] = std::max(max[now], size[to[i]]); } max[now] = std::max(max[now], S - size[now]); if (max[now] < max[root]) root = now; } std::unordered_map<ll, ll> part[110000]; ll min[510000][20]; ll dfn[510000], fat[510000], tot, deep[510000]; ll lg[510000]; void Dfs(ll now, ll f) { deep[now] = deep[f] + 1; fat[now] = f; dfn[now] = ++ tot; min[tot][0] = now; for (ll i = head[now]; i != 0; i = next[i]) { if (to[i] == f) continue; len[to[i]] = len[now] + value[i]; Dfs(to[i], now); } return; } ll Min(ll l, ll r) { if (deep[l] < deep[r]) return l; return r; } void Pretreatment() { Dfs(1, 1); lg[1] = 0; for (ll i = 2; i <= N; ++ i) lg[i] = lg[i >> 1] + 1; for (ll i = N; i >= 1; -- i) { for (ll j = 1; i + (1 << j) - 1 <= N; ++ j) { min[i][j] = Min(min[i][j - 1], min[i + (1 << (j - 1))][j - 1]); } } } ll GetLca(ll u, ll v) { if (u == v) return u; u = dfn[u], v = dfn[v]; if (u > v) std::swap(u, v); u ++; ll len = lg[v - u + 1]; ll answer = Min(min[u][len], min[v - (1 << len) + 1][len]); return fat[answer]; } ll GetDis(ll x, ll y) { if (x == 0 || y == 0) return 0; ll lca = GetLca(x, y); return len[x] + len[y] - 2 * len[lca]; } ll sum[110000]; ll ans[110000], fuck[110000]; ll GetSum(ll now) { ll result = ans[now]; for (ll i = now; fa[i]; i = fa[i]) { result += ans[fa[i]] - fuck[i] + GetDis(now, fa[i]) * (sum[fa[i]] - sum[i]); } return result; } ll Root; ll GetAnswer() { ll now = Root, last = Root; ll has; bool flag = false; while (flag == false) { flag = true; has = GetSum(now); for (ll i = head[now]; i; i = next[i]) { ll temp = GetSum(to[i]); if (has > temp) { flag = false; has = temp; now = to[i]; } } now = part[last][now]; last = now; } return has; } void Solve(ll now) { visit[now] = true; part[now][now] = now; for (ll i = head[now]; i; i = next[i]) { if (visit[to[i]]) continue; S = size[to[i]]; root = 0; GetRoot(to[i], now); part[now][to[i]] = root; fa[root] = now; Solve(root); } } int main() { std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0); std::cin >> N >> Q; for (ll i = 1, u, v, c; i <= N - 1; ++ i) { std::cin >> u >> v >> c; AddEdge(u, v, c); AddEdge(v, u, c); } Pretreatment(); root = 0; max[0] = N + 1; S = N; GetRoot(1, 0); Root = root; Solve(root); for (ll i = 1, u, e; i <= Q; ++ i) { std::cin >> u >> e; for (ll now = u; now; now = fa[now]) { sum[now] += e; ans[now] += GetDis(u, now) * e; if (fa[now]) fuck[now] += GetDis(u, fa[now]) * e; } std::cout << GetAnswer() << '\n'; } }
P7409 SvT
不会虚树,那么直接写
大胡子
#include <bits/stdc++.h> const int MAXN = 5e5 + 1000; int N, M; int num[3100000]; char ch[MAXN]; class Suffix_Array { public: int barrel[MAXN], temp[MAXN]; int SA[MAXN], rank[MAXN], height[MAXN]; void SuffixArray() { int m = 26, n = N; for (int i = 1; i <= m; ++ i) barrel[i] = 0; for (int i = 1; i <= n; ++ i) barrel[rank[i] = ch[i] - 'a' + 1] ++; for (int i = 2; i <= m; ++ i) barrel[i] += barrel[i - 1]; for (int i = n; i >= 1; -- i) SA[barrel[rank[i]] --] = i; for (int w = 1, tot = 0; w <= n; m = tot, tot = 0, w <<= 1) { for (int i = 1; i <= n; ++ i) if (i + w > n) temp[++ tot] = i; for (int i = 1; i <= n; ++ i) if (SA[i] > w) temp[++ tot] = SA[i] - w; for (int i = 1; i <= m; ++ i) barrel[i] = 0; for (int i = 1; i <= n; ++ i) barrel[rank[temp[i]]] ++; for (int i = 2; i <= m; ++ i) barrel[i] += barrel[i - 1]; for (int i = n; i >= 1; -- i) SA[barrel[rank[temp[i]]] --] = temp[i]; tot = 0; std::swap(temp, rank); for (int i = 1; i <= n; ++ i) rank[SA[i]] = (temp[SA[i]] == temp[SA[i - 1]] && temp[SA[i] + w] == temp[SA[i - 1] + w]) ? tot : ++ tot; if (tot == n) return; } } void GetHeight() { int n = N; for (int i = 1, k = 0; i <= n; ++ i) { if (rank[i] == 1) continue; if (k) k --; while (ch[i + k] == ch[SA[rank[i] - 1] + k]) k ++; height[rank[i]] = k; } } }SA; namespace ST { int lg[MAXN]; int ST[MAXN][20]; void Pretreatment() { lg[1] = 0; for (int i = 1; i <= N; ++ i) { if (i >= 2) lg[i] = lg[i >> 1] + 1; ST[i][0] = SA.height[i]; } for (int i = N; i >= 1; -- i) { for (int j = 1; i + (1 << j) - 1 <= N; ++ j) { ST[i][j] = std::min(ST[i][j - 1], ST[i + (1 << (j - 1))][j - 1]); } } } int GetAnswer(int l, int r) { if (l > r) return 0; int len = lg[r - l + 1]; return std::min(ST[l][len], ST[r - (1 << len) + 1][len]); } } long long answer; class Disjoint { public: int fat[3100000]; int size[3100000]; void Pretreatment(int n) { for (int i = 1; i <= n; ++ i) { fat[i] = i; size[i] = 1; } } int Find(int x) { if (fat[x] != x) x = Find(fat[x]); return fat[x]; } void Union(int x, int y, int val) { if (x == y) return; x = Find(x); y = Find(y); if (x != y) { fat[x] = y; answer += 1ll * size[x] * size[y] * val; size[y] += size[x]; } } }set; class Sort { public: int x, y, val; }ask[MAXN * 6]; bool cmp1(const int &a, const int &b) { return SA.rank[a] < SA.rank[b]; } bool cmp2(const Sort &a, const Sort &b) { return a.val > b.val; } std::map<int, int> map; int main() { std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0); std::cin >> N >> M; std::cin >> (ch + 1); N = strlen(ch + 1); SA.SuffixArray(); SA.GetHeight(); ST::Pretreatment(); for (int i = 1, n; i <= M; ++ i) { std::cin >> n; set.Pretreatment(n); int cnt = 0; map.clear(); for (int j = 1, x; j <= n; ++ j) { std::cin >> x; if (!map[x]) num[++ cnt] = x; map[x] ++; } std::sort(num + 1, num + 1 + cnt, cmp1); for (int j = 1; j <= cnt - 1; ++ j) { int left = num[j]; int right = num[j + 1]; ask[j] = {j, j + 1, ST::GetAnswer(SA.rank[left] + 1, SA.rank[right])}; } std::sort(ask + 1, ask + 1 + cnt - 1, cmp2); answer = 0; for (int j = 1; j <= cnt - 1; ++ j) { set.Union(ask[j].x, ask[j].y, ask[j].val); } std::cout << answer << '\n'; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律