diff --git a/src/3/T179940_chat.cpp b/src/3/T179940_chat.cpp new file mode 100644 index 0000000..9d0ce63 --- /dev/null +++ b/src/3/T179940_chat.cpp @@ -0,0 +1,114 @@ +#include +using namespace std; + +typedef long long ll; + +// 定义一个极大值 +const ll INF = 1e18; + +// 线段树支持区间最小查询和点更新 +struct SegmentTree { + int n; + vector tree; + + SegmentTree(int size) { + n = 1; + while(n < size) n <<= 1; + tree.assign(2*n, INF); + } + + // 更新位置 pos (0-based) 的值为val + void update(int pos, ll val) { + pos += n; + tree[pos] = min(tree[pos], val); + while(pos > 1){ + pos >>= 1; + tree[pos] = min(tree[2*pos], tree[2*pos+1]); + } + } + + // 查询区间 [l, r) 的最小值 + ll query(int l, int r) const { + ll res = INF; + int left = l + n; + int right = r + n; + while(left < right){ + if(left & 1){ + res = min(res, tree[left++]); + } + if(right & 1){ + res = min(res, tree[--right]); + } + left >>= 1; + right >>= 1; + } + return res; + } +}; + +int main(){ + ios::sync_with_stdio(false); + cin.tie(0); + int n; + ll m; + cin >> n >> m; + vector a(n); + for(auto &x:a) cin >> x; + + // 计算前缀和 + vector s(n+1, 0); + for(int i=1;i<=n;i++) s[i] = s[i-1] + a[i-1]; + + // 离散化前缀和 + vector all_s = s; + // 还需要 x = s[i] - m + for(int i=0;i<=n;i++) all_s.push_back(s[i] - m); + sort(all_s.begin(), all_s.end()); + all_s.erase(unique(all_s.begin(), all_s.end()), all_s.end()); + + // 映射 s[j] 和 x 到离散化后的索引 + auto get_idx = [&](ll val) -> int { + return lower_bound(all_s.begin(), all_s.end(), val) - all_s.begin(); + }; + + int size = all_s.size(); + // 初始化两个线段树 + SegmentTree st1(size); // 存 dp[j] - s[j] + SegmentTree st2(size); // 存 dp[j] + s[j] + + // 初始化 dp[0] = 0 + // 插入 j=0 的情况 + st1.update(get_idx(s[0]), 0 - s[0]); + st2.update(get_idx(s[0]), 0 + s[0]); + + // 初始化 dp array + // 可以不存储全 dp array,因为只需要 dp[j] 继续更新下去 + vector dp(n+1, INF); + dp[0] = 0; + + for(int i=1;i<=n;i++){ + ll x = s[i] - m; + // 找到 x 在 all_s 中的离散化索引 + // 对于 st1,查询 s[j] <= x + // 找最大的 s[j] <= x,即 upper_bound(x) - 1 + int pos1 = upper_bound(all_s.begin(), all_s.end(), x) - all_s.begin() - 1; + ll res1 = INF; + if(pos1 >= 0){ + res1 = st1.query(0, pos1+1) + x; + } + // 对于 st2,查询 s[j] >= x + // 找最小的 s[j] >= x,即 lower_bound(x) + int pos2 = lower_bound(all_s.begin(), all_s.end(), x) - all_s.begin(); + ll res2 = INF; + if(pos2 < size){ + res2 = st2.query(pos2, size) - x; + } + // 取两者最小值作为 dp[i] + dp[i] = min(res1, res2); + // 更新线段树 + st1.update(get_idx(s[i]), dp[i] - s[i]); + st2.update(get_idx(s[i]), dp[i] + s[i]); + } + + cout << dp[n] << "\n"; +} \ No newline at end of file diff --git a/src/3/T225686.cpp b/src/3/T225686.cpp index 294989d..e9dcfc6 100644 --- a/src/3/T225686.cpp +++ b/src/3/T225686.cpp @@ -1,3 +1,75 @@ +#include +using namespace std; +using ll = int64_t; + +ll n, m; + +pair bfs(ll start, const vector> &adj) { + vector dist(n + 1, -1); + queue q; + q.push(start); + dist[start] = 0; + ll far = start; + + while (!q.empty()) { + ll u = q.front(); q.pop(); + for (auto &v : adj[u]) { + if (dist[v] == -1) { + dist[v] = dist[u] + 1; + q.push(v); + if (dist[v] > dist[far]) { + far = v; + } + } + } + } + return {far, dist[far]}; +} + int main(){ + ios::sync_with_stdio(false); + cin.tie(nullptr); + cin >> n >> m; + vector> adj(n + 1, vector()); + + for (ll i = 0; i < m; i++) { + ll u, v; + cin >> u >> v; + adj[u].push_back(v); + adj[v].push_back(u); + } + + vector vis(n +1, false); + + ll sum_d = 0; + ll k = 0; + for(ll u =1; u <=n; u++) { + if(!vis[u]){ + k++; + auto [ff, fd1] = bfs(u, adj); + auto [sf, sd] = bfs(ff, adj); + sum_d += sd; + + queue qvis; + qvis.push(u); + vis[u] = true; + while(!qvis.empty()){ + ll node = qvis.front(); qvis.pop(); + for(auto &v : adj[node]){ + if(!vis[v]){ + vis[v] = true; + qvis.push(v); + } + } + } + } + } + + if(k == 1){ + cout << sum_d + 1 << '\n'; + } + else{ + cout << sum_d + k << '\n'; + } } \ No newline at end of file diff --git a/src/3/T225686_chat.cpp b/src/3/T225686_chat.cpp new file mode 100644 index 0000000..4cfa1a6 --- /dev/null +++ b/src/3/T225686_chat.cpp @@ -0,0 +1,80 @@ +#include +using namespace std; +using ll = int64_t; + + +ll n, m; +vector> adj; +vector vis_marker; + + +pair bfs(ll start){ + deque q; + q.push_back(start); + ll farthest_node = start; + ll max_distance = 0; + vector dist(n + 1, -1); + dist[start] = 0; + vis_marker[start] = 1; + + while(!q.empty()){ + ll u = q.front(); + q.pop_front(); + for(auto &v : adj[u]){ + if(!vis_marker[v]){ + vis_marker[v] = 1; + dist[v] = dist[u] + 1; + q.push_back(v); + if(dist[v] > max_distance){ + max_distance = dist[v]; + farthest_node = v; + } + } + } + } + return {farthest_node, max_distance}; +} + +int main(){ + ios::sync_with_stdio(false); + cin.tie(NULL); + + cin >> n >> m; + adj.assign(n + 1, vector()); + ll u, v; + + for(ll i = 0; i < m; ++i){ + cin >> u >> v; + adj[u].emplace_back(v); + adj[v].emplace_back(u); + } + + + vis_marker.assign(n + 1, 0); + + ll sum_d = 0; + ll k = 0; + + for(ll u = 1; u <= n; ++u){ + if(!vis_marker[u]){ + k++; + + pair first_bfs = bfs(u); + ll ff = first_bfs.first; + + + pair second_bfs = bfs(ff); + ll sd = second_bfs.second; + + sum_d += sd; + } + } + + + if(k == 1){ + cout << sum_d + 1 << '\n'; + } + else{ + cout << sum_d + k << '\n'; + } +} \ No newline at end of file diff --git a/src/3/T585518_chat.cpp b/src/3/T585518_chat.cpp new file mode 100644 index 0000000..13be19a --- /dev/null +++ b/src/3/T585518_chat.cpp @@ -0,0 +1,60 @@ +#include +using namespace std; + +// 定义无向图的邻接表表示 +vector> adj; + +// BFS函数,返回从起点开始的所有节点的距离 +vector bfs(int start, int n) { + vector dist(n + 1, -1); // 节点编号从1到n + queue q; + q.push(start); + dist[start] = 0; + while (!q.empty()) { + int u = q.front(); q.pop(); + for(auto &v : adj[u]) { + if(dist[v] == -1){ + dist[v] = dist[u] + 1; + q.push(v); + } + } + } + return dist; +} + +int main(){ + ios::sync_with_stdio(false); + cin.tie(0); + + int n; + cin >> n; + adj.assign(n + 1, vector()); + for(int i=0;i> u >> v; + adj[u].push_back(v); + adj[v].push_back(u); + } + + // 第一次 BFS,找出u + vector dist1 = bfs(1, n); + int u = 1; + for(int i=1;i<=n;i++) { + if(dist1[i] > dist1[u]) u = i; + } + + // 第二次 BFS,从u找出v,并记录d1 + vector d1 = bfs(u, n); + int v = u; + for(int i=1;i<=n;i++) { + if(d1[i] > d1[v]) v = i; + } + + // 第三次 BFS,从v找出d2 + vector d2 = bfs(v, n); + + // 输出每个节点的最远距离 + for(int i=1;i<=n;i++) { + cout << max(d1[i], d2[i]) << (i==n ? '\n' : ' '); + } +} \ No newline at end of file diff --git a/src/test.cpp b/src/test.cpp new file mode 100644 index 0000000..394e26d --- /dev/null +++ b/src/test.cpp @@ -0,0 +1,55 @@ +#include +#include +#include +using namespace std; + +struct TreeNode { + vector children; +}; + +vector tree; +vector enjoyment; +vector> dp; + +void dfs(int u, int parent) { + dp[u][0] = 0; + dp[u][1] = enjoyment[u]; + + for (int v : tree[u].children) { + if (v == parent) continue; + dfs(v, u); + dp[u][0] += max(dp[v][0], dp[v][1]); + dp[u][1] += dp[v][0]; + } + + 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); + } +} + +int main() { + int n, b; + cin >> n >> b; + enjoyment.resize(n + 1); + tree.resize(n + 1); + dp.resize(n + 1, vector(2)); + + for (int i = 1; i <= n; ++i) { + cin >> enjoyment[i]; + } + + for (int i = 0; i < n - 1; ++i) { + int x, y; + cin >> x >> y; + tree[x].children.push_back(y); + tree[y].children.push_back(x); + } + + dfs(1, -1); + long long result = max(0LL, max(dp[1][0], dp[1][1])); + cout << result << endl; + + return 0; +} \ No newline at end of file