总结

ABC没什么说的,D体面没读明白,vp的时候没做出来。E题计算lca的时候少跳了一步,调了很久才发现,说明对板子还是有些生疏。从F题学到了线段树的一种类似二分的查询方法,学到了set的erase函数返回值是删掉的迭代器的下一个。

A. USB Flash Drives

题意

给你一些U盘,每个U盘能存储一定大小的数据,求存储一定大小的数据至少需要多少U盘。

思路

将U盘从大到小排序,贪心选就是最优的答案。复杂度 O(nlog⁡n)O(n \log n)O(nlogn) 。

代码

#include <bits/stdc++.h>
using namespace std;signed main() {ios::sync_with_stdio(false);cin.tie(0);int n, m; cin >> n >> m;vector<int> a(n);for(int i = 0; i<n; i++) cin >> a[i];sort(a.begin(), a.end());reverse(a.begin(), a.end());int cnt = 0;for(int i = 0; i<n; i++) {if(m - a[i] > 0) {m -= a[i];cnt++;} else {cout << cnt+1 << "\n";break;}}return 0;
}

B. The Best Gift

题意

给 nnn (n≤2⋅105)(n \leq 2 \cdot 10^5)(n≤2⋅105) 本书,每本有一个种类 (种类的数量不超过101010),现在想选两本不同种类的书,求一共有多少种选法。

思路

开一个桶,记录每种书籍出现的次数,再暴力枚举种类,计算方案数量。复杂度 O(n+m2)O(n + m^2)O(n+m2) 。

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long;signed main() {ios::sync_with_stdio(false);cin.tie(0);int n, m; cin >> n >> m;vector<int> cnt(m+1);for(int i = 0; i<n; i++) {int x; cin >> x; cnt[x]++;}vector<int> v;for(int i = 1; i<=m; i++) if(cnt[i]) v.push_back(cnt[i]);ll ans = 0;for(int i = 0; i<v.size(); i++) {for(int j = i+1; j<v.size(); j++) {ans += v[i]*v[j];}}cout << ans << "\n";return 0;
}

C. Load Balancing

题意

给一个长度为 nnn (n≤105)(n \leq 10^5)(n≤105) 的序列,可以使用一代价,让其中一个值加一,另一个值减一。求使序列极差最小需要的最小代价。

思路

将原序列 aaa 升序排列,创建一个新序列 bbb 为目标序列,同样的要保证升序。iii 从 111 到 nnn 枚举,如果 ai>bia_i \gt b_iai​>bi​,把么就需要 ai−bia_i - b_iai​−bi​ 的代价将 aia_iai​ 减为 bib_ibi​ 。如果 ai<bia_i \lt b_iai​<bi​,就不需要考虑,因为值增加与值减少是对应的,只需要考虑一种即可。复杂度 O(nlog⁡n)O(n \log n)O(nlogn) 。

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long;signed main() {ios::sync_with_stdio(false);cin.tie(0);int n; cin >> n;vector<int> a(n);for(int i = 0; i<n; i++) cin >> a[i];sort(a.begin(), a.end());int sum = accumulate(a.begin(), a.end(), 0);vector<int> b(n, sum / n);for(int i = n-1; i>n-1-sum%n; i--) b[i]++;int ans = 0;for(int i = 0; i<n; i++) if(a[i] > b[i]) ans += a[i] - b[i];cout << ans << "\n";return 0;
}

D. Gadgets for dollars and pounds

题意

总共有 mmm (m≤2⋅105)(m \leq 2 \cdot 10^5)(m≤2⋅105) 种商品需要你从中购买 kkk (k≤m)(k \leq m)(k≤m) 个,你有 sss (m≤109)(m \leq 10^9)(m≤109) 个金币。每种商品可以使用一定数量的美元或英镑购买。一共有 nnn (n≤2⋅105)(n \leq 2 \cdot 10^5)(n≤2⋅105) 天,每天有不同的金币兑换美元英镑的汇率。求至少需要多少天才能买到 kkk 个商品。

思路

显然具有两段性,可以二分答案。下面考虑对于一个答案 xxx 如何去检查是否可行。

先找到前 xxx 天美元英镑汇率的最小值。如果我们要购买需要使用美元购买的商品,那么一定是在前 xxx 天美元汇率最低的一天进行购买。英镑同理。根据美元英镑的最低汇率,将商品的代价均转化为金币,按金币的价格升序排列,从小到大贪心计算最多能购买多少商品。

复杂度 O(nlog⁡2n)O(n \log^2n)O(nlog2n) 。

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long;const int maxn = 2e5+20;
int a[maxn], b[maxn];
int t[maxn], c[maxn];
pair<int, int> ans[maxn];int n, m, k, s;bool check(int x) {int posa = min_element(a, a+x) - a;int posb = min_element(b, b+x) - b;// cerr << posa << " " << posb << endl;vector<pair<ll, int>> v;for(int i = 0; i<m; i++) {if(t[i] == 1) v.emplace_back((ll) c[i] * a[posa], i);else          v.emplace_back((ll) c[i] * b[posb], i);}sort(v.begin(), v.end());ll need = 0;for(int i = 0; i<k; i++) need += v[i].first;if(need <= s) {for(int i = 0; i<k; i++){int p = v[i].second;if(t[p] == 1) ans[i] = {posa, p};else          ans[i] = {posb, p};}return true;} else return false;
}signed main() {ios::sync_with_stdio(false);cin.tie(0);cin >> n >> m >> k >> s;for(int i = 0; i<n; i++) cin >> a[i];for(int i = 0; i<n; i++) cin >> b[i];for(int i = 0; i<m; i++) cin >> t[i] >> c[i];if(!check(n)) {cout << -1 << "\n";return 0;}int l = 1, r = n;while(l < r) {int mid = l + r >> 1;if(check(mid)) r = mid;else l = mid+1;}cout << l << "\n";for(int i = 0; i<k; i++) cout << ans[i].second+1 << " " << ans[i].first+1 << "\n";return 0;
}

E. Minimum spanning tree for each edge

题意

给定简单无向图,边数点数最多均为 2⋅1052 \cdot 10^52⋅105,对于每一条边,求包含这条边的最小生成树边权和。

思路

先求出这个图的最小生成树边权和。对于每一条边,看作一次询问。如果这条边恰好在最小生成树上,直接输出整张图的最小生成树边权和;如果不在,需要在原图的最小生成树上将这条边加上,这样就会出现一个环,再将环上的最大边权的边减去,得到的就是包含这条边的最小生成树。

考虑代码实现。不需要建立原图。读取每一条边,使用kruskal算法求出给定图的最小生成树,并将生成树建立出来。再跑一遍lca算法,不仅要处理出每个点向上跳到的祖先,还需要处理出每个点向上跳到某个祖先路径上的最大边权。对于不在生成树上的边 u−vu - vu−v 的询问,假设将这条边加到树上,环一定是由 u−lcau - lcau−lca、lca−vlca - vlca−v、v−uv - uv−u,构成的,那么我们删去的边就是 uuu 到 lcalcalca 与 vvv 到 lcalcalca 路径上的最长的一条。

复杂度 O(nlog⁡n+mlog⁡m)O(n \log n + m \log m)O(nlogn+mlogm) 。

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long;const int maxn = 2e5+20;
const int maxm = 4e5+20;
int h[maxn], e[maxm], w[maxm], ne[maxm], top;
void add(int a, int b, int c) {e[top] = b, w[top] = c, ne[top] = h[a], h[a] = top++;
}
ll ans[maxn];
int n, m;int p[maxn];
int find(int x) {if(x != p[x]) p[x] = find(p[x]);return p[x];
}struct Edge {int id, x, y, w;bool used;bool operator < (const Edge& o) const {return w < o.w;}
} edges[maxm];ll kruskal() {ll ret = 0;sort(edges, edges+m);for(int i = 0; i<m; i++) {Edge& e = edges[i];int x = e.x, y = e.y, w = e.w;int px = find(x), py = find(y);if(px != py) {e.used = true;add(x, y, w); add(y, x, w);p[px] = py;ret += w;}}return ret;
}int depth[maxn];
int fa[maxn][19];
int mx[maxn][19];
void bfs(int root){memset(depth, 0x3f, sizeof depth);depth[0] = 0; depth[root] = 1;queue<int> q; q.push(root);while(!q.empty()){int u = q.front(); q.pop();for(int i = h[u]; ~i; i = ne[i]) {int v = e[i];if(depth[v] > depth[u] + 1){depth[v] = depth[u] + 1;q.push(v);fa[v][0] = u, mx[v][0] = w[i];for(int k = 1; k<=18; k++)fa[v][k] = fa[fa[v][k-1]][k-1], mx[v][k] = max(mx[v][k-1], mx[fa[v][k-1]][k-1]);}}}
}int query(int a, int b){int ret = 0;if(depth[a] < depth[b]) swap(a, b);for(int k = 18; k>=0; k--)if(depth[fa[a][k]] >= depth[b])ret = max(ret, mx[a][k]), a = fa[a][k];if(a == b) return ret;for(int k = 18; k>=0; k--)if(fa[a][k] != fa[b][k]) {ret = max({ret, mx[a][k], mx[b][k]});a = fa[a][k], b = fa[b][k];}return max({ret, mx[a][0], mx[b][0]});
}signed main() {ios::sync_with_stdio(false);cin.tie(0);memset(h, -1, sizeof h);for(int i = 0; i<maxn; i++) p[i] = i;cin >> n >> m;for(int i = 0; i<m; i++) {Edge& e = edges[i]; e.id = i;cin >> e.x >> e.y >> e.w;}ll tot = kruskal();bfs(1);for(int i = 0; i<m; i++) {Edge& e = edges[i];if(e.used) ans[e.id] = tot;else ans[e.id] = tot + e.w - query(e.x, e.y);}for(int i = 0; i<m; i++) cout << ans[i] << "\n";return 0;
}

F. Frogs and mosquitoes

题意

给 nnn 只青蛙,坐落在数轴上,每只青蛙有位置 xxx、舌头长度 ttt 两个属性。给一个蚊子序列,蚊子有位置 ppp 、大小 bbb 两个属性。现在所有蚊子从前到后依次尝试降落。对于一只蚊子,如果有一只青蛙满足 x+t>=px + t >= px+t>=p 和 x<=px <= px<=p 两个条件,这个青蛙就会吃掉这只蚊子,同时舌头长度会增加 bbb 。如果长度增加使得青蛙能够吃到停留在坐标轴上的新的蚊子,青蛙就会继续吃下去。对于一只蚊子,如果多个青蛙都能吃到,那么最左边的青蛙会吃掉它;如果没有青蛙能吃到,那么这只蚊子就会降落到坐标轴上它的位置。

思路

使用线段树维护每只青蛙能够吃到的最远点。用一个multiset维护降落到坐标轴上的蚊子。从前至后枚举蚊子序列,找到第一个能吃它的青蛙,这只青蛙将它吃掉后,不断地吃坐标轴上的其它蚊子。如果没有青蛙能够吃掉这只蚊子,就将蚊子放进multiset中。复杂度 O(nlog⁡n+mlog⁡m)O(n \log n + m \log m)O(nlogn+mlogm) 。

代码

#include <bits/stdc++.h>
using namespace std;const int maxn = 2e5+20;
int n, m;struct Node {int x, t, id;bool operator < (const Node &o) const {return x < o.x;}
} a[maxn];int sum[maxn], ans[maxn];int val[maxn * 4];void build(int u, int l, int r) {if(l == r) val[u] = a[l].x + a[l].t;else {int mid = l + r >> 1;build(u << 1, l, mid); build(u << 1 | 1, mid+1, r);val[u] = max(val[u << 1], val[u << 1 | 1]);}
}int query(int u, int l, int r, int x) {if(l == r) return l;int mid = l + r >> 1;if(val[u << 1] >= x) return query(u << 1, l, mid, x);else return query(u << 1 | 1, mid+1, r, x);
}void modify(int u, int l, int r, int x, int v) {if(l == r) val[u] = v;else {int mid = l + r >> 1;if(mid >= x) modify(u << 1, l, mid, x, v);else modify(u << 1 | 1, mid+1, r, x, v);val[u] = max(val[u << 1], val[u << 1 | 1]);}
}signed main() {ios::sync_with_stdio(false);cin.tie(0);cin >> n >> m;for(int i = 1; i<=n; i++) cin >> a[i].x >> a[i].t, a[i].id = i;sort(a+1, a+1+n);build(1, 1, n);multiset<pair<int, int> > st;for(int i = 1; i<=m; i++) {int p, b; cin >> p >> b;int x = query(1, 1, n, p);if(a[x].x + a[x].t < p || a[x].x > p) st.insert({p, b});else {auto it = st.lower_bound({a[x].x + a[x].t, 0});a[x].t += b;sum[a[x].id] ++;while(it != st.end() && it->first <= a[x].x + a[x].t) {a[x].t += it->second;sum[a[x].id]++;it = st.erase(it);}modify(1, 1, n, x, a[x].x + a[x].t);}}for(int i = 1; i<=n; i++) ans[a[i].id] = a[i].t;for(int i = 1; i<=n; i++) cout << sum[i] << " " << ans[i] << "\n";return 0;
}

【板刷 educational round】Educational Codeforces Round 3 A - F相关推荐

  1. [Educational Codeforces Round 16]A. King Moves

    [Educational Codeforces Round 16]A. King Moves 试题描述 The only king stands on the standard chess board ...

  2. Educational Codeforces Round 114 (Rated for Div. 2) (A ~ F)全题解

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Educational Codeforces Round 114 (Rated for Div. 2) ...

  3. Educational Codeforces Round 106 (Rated for Div. 2)(A ~ E)题解(每日训练 Day.16 )

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 Educational Codeforces Round 106 (Rated for Div. ...

  4. Educational Codeforces Round 32

    http://codeforces.com/contest/888 A Local Extrema[水] [题意]:计算极值点个数 [分析]:除了第一个最后一个外,遇到极值点ans++,包括极大和极小 ...

  5. Educational Codeforces Round 37 (Rated for Div. 2) 1

    Educational Codeforces Round 37 (Rated for Div. 2) A.Water The Garden 题意:Max想给花园浇水.花园可被视为长度为n的花园床,花园 ...

  6. Educational Codeforces Round 90 (Rated for Div. 2)(A, B, C, D, E)

    Educational Codeforces Round 90 (Rated for Div. 2) Donut Shops 思路 分三种情况: a==c/ba == c / ba==c/b这个时候两 ...

  7. Educational Codeforces Round 89 (Rated for Div. 2)(A, B, C, D)

    Educational Codeforces Round 89 (Rated for Div. 2) A. Shovels and Swords 思路 题意非常简单,就是得到最多的物品嘛,我们假定a, ...

  8. Educational Codeforces Round 114 (Rated for Div. 2) D. The Strongest Build 暴力 + bfs

    传送门 文章目录 题意: 思路: 题意: 你有nnn个装备槽,每个槽里面有cic_ici​个力量加成,对于每个槽只能选一个力量加成,现在给你mmm个力量组合[b1,b2,...,bn][b_1,b_2 ...

  9. Educational Codeforces Round 17 E. Radio stations cdq分治 + 树状数组

    传送门 文章目录 题意 思路: 题意 有nnn个电台,对于每个电台iii有三个参数xi,ri,fix_i,r_i,f_ixi​,ri​,fi​,分别指他们的坐标.作用半径.频率.如果两个电台频率差值在 ...

  10. Educational Codeforces Round 16 C. Magic Odd Square 矩阵构造

    传送门 文章目录 题意: 思路: 题意: 给你一个奇数nnn,让你构造一个n∗nn*nn∗n的矩阵,矩阵的每个位置依次填上[1,n∗n]之内的数[1,n*n]之内的数[1,n∗n]之内的数,满足每行. ...

最新文章

  1. tomcat怎么平滑更新项目_tomcat_deploy 平滑启动脚本
  2. php转调页面,PHP中HTTP防盗链技术
  3. java 加密_Java版SMS4加密解密算法
  4. lintcode-517-丑数
  5. 《深入Linux内核》 UNIX的一些故事
  6. 利用微软AntiXss Library过滤输出字符,防止XSS攻击
  7. 将json数据转换成实体对象 JSON格式转换 JSON实体
  8. Apache ECharts教程
  9. OpenCV识别指定颜色(黑、灰、白、红、橙、黄、绿、青、蓝、紫)
  10. TDB和SPARQL
  11. 数据挖掘综合应用:数据预处理代码实战
  12. 微信小程序之小程序UI组件、开发框架、实用库学习资源汇总-建议收藏
  13. Qt 之文件选择对话框 QFileDialog
  14. OllyDbg断点详解
  15. 【中文】【吴恩达课后编程作业】Course 4 - 卷积神经网络 - 第二周作业
  16. Android Strongbox( Android Ready SE)
  17. 高级程序员如何面对职场压力 1 --老板是猪头
  18. aip文档服务器已停止工作,ColdFusion的11 REST API服务似乎意外地停止工作
  19. GitHub文件大小限制及相关建议
  20. Adobe全家桶,设计师福利

热门文章

  1. 3sigma模型案例分析彻底搞懂置信度与置信区间
  2. python sklearn 置信概率
  3. 免费抄袭检测的网站汇总
  4. Springboot橘子酒店管理系统eg48i计算机毕业设计-课程设计-期末作业-毕设程序代做
  5. AE平面跟踪和视觉效果插件mocha pro mac破解版
  6. 华南师范大学c语言考研真题,2017年华南师范大学计算机学院925数据结构考研题库...
  7. Tomcat异常:The ResourceConfig instance does not contain any root resource classes
  8. 工业六轴机器人常见的STD(标准)-DH模型建立方法
  9. 广东计算机高职高考能考本科,广东高职高考(3+证书)2021年考本科须知
  10. ubuntu忘记root密码怎么办?linux 进入recovery模式,ubuntu进入recovery mode模式