Codeforces Round 975 (Div. 2)(A,B,C,D线段树解法,E)

server/2024/10/20 12:05:20/

比赛链接

https://codeforces.com/contest/2019

A题

思路

分别求出奇数位和偶数位的最大值,之后进行比较即可。

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e2 + 5;
int n;
int a[N];
void solve()
{cin >> n;for (int i = 1; i <= n; i++){cin >> a[i];}int maxx1 = 0, maxx2 = 0, ans1 = 0, ans2 = 0;for (int i = 1, j = 2; i <= n; i += 2, j += 2){maxx1 = max(maxx1, a[i]);ans1++;if (j <= n){ans2++;maxx2 = max(maxx2, a[j]);}}cout << max(maxx1 + ans1, maxx2 + ans2) << endl;
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int test = 1;cin >> test;for (int i = 1; i <= test; i++){solve();}return 0;
}

B题

思路

我们考虑预处理出每一个区间对答案产生的贡献。考虑每个区间以第 a i a_{i} ai个为端点,到 a i + 1 a_{i+1} ai+1中间的数对答案产生的贡献。

对第 i i i个端点的贡献和为 ( n − i + 1 ) × ( i − 1 ) + ( n − i ) (n-i+1)\times (i-1) + (n-i) (ni+1)×(i1)+(ni),即以 a i a_{i} ai为端点产生的贡献。

对第 a i + 1 a_{i}+1 ai+1 a i + 1 a_{i+1} ai+1之间的数对答案产生的贡献为 i × ( n − i ) i\times (n-i) i×(ni)

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 5;
int n, q, k;
int a[N];
void solve()
{cin >> n >> q;for (int i = 1; i <= n; i++){cin >> a[i];}map<int, int> mp;mp[n - 1] += (a[2] - a[1]);mp[n - 1]++;for (int i = 2; i < n; i++){int op = n - i + 1;int cnt = i - 1;mp[cnt * op + (n - i)]++;mp[(op - 1) * (cnt + 1)] += (a[i + 1] - a[i] - 1);}while (q--){cin >> k;cout << mp[k] << " ";}cout << endl;
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int test = 1;cin >> test;for (int i = 1; i <= test; i++){solve();}return 0;
}

C题

思路

可以分两种情况进行讨论。

根据题意,我们最多可以将卡牌分为 n n n组。

我们规定 s u m sum sum表示原先卡牌个数的总和, m a x x maxx maxx表示卡牌个数最多的那个卡牌类型的数量。

k = 0 k=0 k=0的时候,只需要对原先的卡牌进行分组即可。我们假设可以将每 i i i个卡牌分为一组,如果 s u m % i = = 0 sum \% i == 0 sum%i==0并且 s u m / i ≥ m a x x sum/i \ge maxx sum/imaxx,则可以将卡牌分为每 i i i个一组。我们直接对答案进行暴力枚举即可。

k > 0 k > 0 k>0的时候,我们依旧假设可以将每 i i i个卡牌分为一组,对于我们最后一组的卡牌,会有 s u m % i sum \% i sum%i个,如果我们想要将其补全,需要再添加 o p = i − s u m % i op = i - sum \% i op=isum%i个卡牌。如果 k < o p k < op k<op,则不可将卡牌分为每 i i i个一组。否则,我们令 r e s = ( s u m + o p ) / i + ( k − o p ) / i res = (sum + op) / i + (k - op) / i res=(sum+op)/i+(kop)/i,如果 r e s ≥ m a x x res \ge maxx resmaxx,则 i i i为可行的答案。

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 5;
int n, k, sum;
int a[N];
void solve()
{cin >> n >> k;sum = 0;for (int i = 1; i <= n; i++){cin >> a[i];sum += a[i];}int maxx = *max_element(a + 1, a + 1 + n);if (k == 0){int ans = 1;for (int i = 1; i <= n; i++){if (sum % i == 0 && sum / i >= maxx){ans = i;}}cout << ans << endl;}else{int ans = 1;for (int i = 2; i <= n; i++){int op = i - sum % i;if (op == i)op = 0;if (op > k)continue;int res = (sum + op) / i + (k - op) / i;if (res < maxx)continue;ans = i;}cout << ans << endl;}
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int test = 1;cin >> test;for (int i = 1; i <= test; i++){solve();}return 0;
}

D题

思路

这里提供一个线段树的做法。

我们假设以点 i i i为起点,向两端不断扩散。对于 i i i点左边的点 j j j,其必须在 j j j点左端的点前被征服。对于 i i i点右边的点 k k k,其必须在 k k k点右端的点前被征服。

因此,我们可以预处理出前缀最小值和后缀最小值。

对于每一个起点 i i i,必然有一套单独的 v e c t o r < i n t > d f n vector<int>dfn vector<int>dfn表示每一个点最晚可以在什么时刻被征服,而这个 d f n dfn dfn值便是前面说的 i i i点左边点的前缀最小值,和 i i i点右边点的后缀最小值。

我们对于每一个 d f n i dfn_{i} dfni,将区间 [ d f n i , n ] [dfn_{i},n] [dfni,n]全部加上一个正整数 1 1 1。表示在 [ d f n i , n ] [dfn_{i},n] [dfni,n]这个时间节段的每一个节点已经被征服了多少个点。

处理完 d f n dfn dfn之后,我们对 1 1 1 n n n的区间,每一个点都减去对应的时间。即第 i i i个点减去 i i i

如果最后出现大于 0 0 0的情况,则表示第 i i i个点无法作为起点。

因此我们可以用线段树动态维护区间最大值,区间查询操作为加减,枚举每一个 i i i作为起点时是否可行,直接统计答案即可。

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 5;
const int inf = 0x3f3f3f3f3f3f3f3f;
int n;
int a[N], nxt[N];
vector<int>p(N);
struct segmenttree
{struct node{int l, r, maxx, tag;};vector<node>tree;segmenttree(): tree(1) {}segmenttree(int n): tree(n * 4 + 1) {}void pushup(int u){auto &root = tree[u], &left = tree[u << 1], &right = tree[u << 1 | 1];root.maxx = max(left.maxx, right.maxx);}void pushdown(int u){auto &root = tree[u], &left = tree[u << 1], &right = tree[u << 1 | 1];if (root.tag != 0){left.tag += root.tag;right.tag += root.tag;left.maxx = left.maxx + root.tag;right.maxx = right.maxx + root.tag;root.tag = 0;}}void build(int u, int l, int r){auto &root = tree[u];root = {l, r};if (l == r){root.maxx = -p[r];}else{int mid = l + r >> 1;build(u << 1, l, mid);build(u << 1 | 1, mid + 1, r);pushup(u);}}void modify(int u, int l, int r, int val){auto &root = tree[u];if (root.l >= l && root.r <= r){root.maxx += val;root.tag += val;return;}pushdown(u);int mid = root.l + root.r >> 1;if (l <= mid) modify(u << 1, l, r, val);if (r > mid) modify(u << 1 | 1, l, r, val);pushup(u);}int query(int u, int l, int r){auto &root = tree[u];if (root.l >= l && root.r <= r){return root.maxx;}pushdown(u);int mid = root.l + root.r >> 1;int res = -inf;if (l <= mid) res = query(u << 1, l, r);if (r > mid) res = max(res, query(u << 1 | 1, l, r));return res;}
};
void init()
{iota(p.begin(), p.end(), 0);
}
void solve()
{cin >> n;for (int i = 1; i <= n; i++){cin >> a[i];}segmenttree smt(n);smt.build(1, 1, n);nxt[n] = a[n];for (int i = n - 1; i >= 1; i--){nxt[i] = min(nxt[i + 1], a[i]);}for (int i = 1; i <= n; i++){smt.modify(1, nxt[i], n, 1);}int ans = 0, last = inf;for (int i = 1; i <= n; i++){smt.modify(1, nxt[i], n, -1);smt.modify(1, 1, n, 1);if (smt.query(1, 1, n) <= 0) ans++;smt.modify(1, 1, n, -1);last = min(last, a[i]);smt.modify(1, last, n, 1);}cout << ans << endl;
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int test = 1;cin >> test;init();for (int i = 1; i <= test; i++){solve();}return 0;
}

E题

思路

统计每一个节点所能到达的最大深度。

枚举以第 i i i层为结果计算答案,则第 i i i层的答案为深度 > i >i >i的节点的个数 + + +最大深度 < i <i <i的节点的个数。

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 5e5 + 5;
const int inf = 0x3f3f3f3f3f3f3f3f;
int n;
int depth[N], maxdeep[N], cnt[N], pre[N];
vector<int> mp[N];
void dfs(int u, int fu, int deep)
{depth[u] = deep;maxdeep[u] = deep;cnt[deep]++;for (int j : mp[u]){if (j == fu) continue;dfs(j, u, deep + 1);maxdeep[u] = max(maxdeep[u], maxdeep[j]);}
}
void solve()
{cin >> n;for (int i = 0; i <= n; i++){depth[i] = maxdeep[i] = cnt[i] = pre[i] = 0;mp[i].clear();}for (int i = 1, u, v; i < n; i++){cin >> u >> v;mp[u].push_back(v);mp[v].push_back(u);}dfs(1, -1, 1);for (int i = 1; i <= n; i++){pre[maxdeep[i]]++;cnt[i] += cnt[i - 1];}int ans = inf;for (int i = 1; i <= n; i++){pre[i] += pre[i - 1];ans = min(ans, pre[i - 1] + n - cnt[i]);}cout << ans << endl;
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int test = 1;cin >> test;for (int i = 1; i <= test; i++){solve();}return 0;
}

http://www.ppmy.cn/server/125345.html

相关文章

AtCoder Beginner Contest 373(ABCDEF 题)视频讲解

A - September Problem Statement There are 12 12 12 strings S 1 , S 2 , … , S 12 S_1, S_2, \ldots, S_{12} S1​,S2​,…,S12​ consisting of lowercase English letters. Find how many integers i i i ( 1 ≤ i ≤ 12 ) (1 \leq i \leq 12) (1≤i≤12) satisfy …

StopWath,apache commons lang3 包下的一个任务执行时间监视器的使用

StopWath是 apache commons lang3 包下的一个任务执行时间监视器&#xff0c;与我们平时常用的秒表的行为比较类似&#xff0c;我们先看一下其中的一些重要方法&#xff1a; <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> <dependen…

高效学习工作SMART原则

S代表Specific&#xff08;明确具体的&#xff09;&#xff0c;意味着你需要清晰地定义你的目标&#xff0c;并确保它是具体而明确的。例如&#xff0c;如果你的目标是“提高销售”&#xff0c;那么这个目标就不是足够具体。更好的表述可能是&#xff1a;“在接下来的三个月内&…

http代理池子大小要如何判断?

最近经常刷到关于如何判断HTTP代理池大小的话题&#xff0c;很多朋友对此感到困惑。那么&#xff0c;今天我们就一起来探讨这个问题。 HTTP代理池的基本概念 在我们深入探讨如何判断HTTP代理池大小之前&#xff0c;先来了解一下什么是HTTP代理池。HTTP代理池是由多个HTTP代理…

easyExcel使用模版填充excel,合并单元格

一、最终效果 二、制作模版 1、制作填充模版 模版在代码中保存的位置 2、Controller /*** 下载模板*/ RequestMapping(value "exportData") public void exportData(KqKqb kqKqb,HttpServletResponse response, HttpServletRequest request) throws IOExceptio…

Linux基础(二):磁盘分区

1.磁盘在Linux中的文件名 SATA接口的磁盘在Linux中名字为/dev/sdx。/dev 几乎是所有外接设备存放的文件夹&#xff1a; 磁盘在Linux中的文件名是不确定的&#xff0c;比如拿一个U盘插到Linux主机&#xff0c;可能第一次名字为sda&#xff0c;拔插后名字为sdc&#xff0c;这取…

网盘能否作为FTP替代产品?企业该如何进行FTP国产化替代?

近年来&#xff0c;信创的概念引入和高效实践落地让更多的行业企业自发性地进行国产化替代&#xff0c;目前信创国产化替代还多发生在操作系统和应用层面&#xff0c;软件工具等目前还在下一阶段规划&#xff0c;但很多企业未雨绸缪&#xff0c;已经在做调研和尝试。 FTP作为世…

uniapp中实现评分组件,多用于购买商品后,对商品进行评价等场景

前言 uni-rate是uniapp框架中提供的一个评分组件。它可以用于用户评价、打分等场景。uni-rate组件可以根据设定的星星总数&#xff0c;展示用户评分的效果&#xff0c;用户可以通过点击星星或滑动星星的方式进行评分。同时&#xff0c;uni-rate组件也支持自定义星星图标、星星…