Codeforces Round #882 (Div. 2) A-D
A
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int a[107];
int f[107];
bool solve() {
int n, k;
cin >> n >> k;
for (int i = 1;i <= n;i++) cin >> a[i];
for (int i = 1;i <= n - 1;i++) f[i] = abs(a[i + 1] - a[i]);
sort(f + 1, f + n);
int sum = 0;
for (int i = 1;i <= n - k;i++) sum += f[i];
cout << sum << '\n';
return true;
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}
B
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
bool solve() {
int n;
cin >> n;
int sum = ~(1 << 31), cnt = 0;
for (int i = 1;i <= n;i++) {
int x;
cin >> x;
sum &= x;
if (sum == 0) cnt++, sum = ~(1 << 31);
}
cout << max(cnt, 1) << '\n';
return true;
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}
C
题意
开始时有 \(n\) 个数,每次操作可以取一个后缀异或和放到所有数后面,问能取到的最大数字是多少。
题解
方法一
知识点:位运算,字典树。
我们发现,无论我们怎么取,取到的值一定是原来 \(n\) 个数字的一个连续段的异或和,因此问题变成求最大子段异或和。
最大子段异或和非常经典,可以用01Trie解决。
时间复杂度 \(O(8n)\)
空间复杂度 \(O(8n)\)
方法二
知识点:位运算,枚举。
这里只有 \(2^8\) ,所以也可以枚举。
时间复杂度 \(O(n2^8)\)
空间复杂度 \(O(n)\)
代码
方法一
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
class Trie {
struct Node {
array<int, 2> nxt;
int val;
};
int bit;
vector<Node> node;
Node NIL;
public:
Trie(int _bit = 0) { init(_bit); }
void init(int _bit) {
bit = _bit;
NIL = { {0,0},0 };
node.assign(1, NIL);
}
void insert(int s) {
int p = 0;
for (int i = bit - 1;i >= 0;i--) {
int c = (s >> i) & 1;
if (!node[p].nxt[c]) {
node[p].nxt[c] = node.size();
node.push_back(NIL);
}
p = node[p].nxt[c];
}
node[p].val = s;
}
int find(int s) {
int p = 0;
for (int i = bit - 1;i >= 0;i--) {
int c = (s >> i) & 1;
if (node[p].nxt[c ^ 1]) p = node[p].nxt[c ^ 1];
else p = node[p].nxt[c];
}
return node[p].val;
}
};
int a[100007];
bool solve() {
int n;
cin >> n;
for (int i = 1;i <= n;i++) cin >> a[i];
Trie trie(8);
trie.insert(0);
int sum = 0, ans = 0;
for (int i = 1;i <= n;i++) {
sum ^= a[i];
ans = max(ans, sum ^ trie.find(sum));
trie.insert(sum);
}
cout << ans << '\n';
return true;
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}
代码二
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int a[100007];
bool solve() {
int n;
cin >> n;
for (int i = 1;i <= n;i++) cin >> a[i];
vector<int> vis(1 << 8);
int sum = 0, ans = 0;
vis[0] = 1;
for (int i = 1;i <= n;i++) {
sum ^= a[i];
for (int j = 0;j < (1 << 8);j++)
if (vis[j]) ans = max(ans, sum ^ j);
vis[sum] = 1;
}
cout << ans << '\n';
return true;
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}
D
题意
给定一个长为 \(n\) 的 \(01\) 串 \(s\) ,取其 \(m\) 个子串 \(s[l_i,r_i]\) ,按取的顺序从左到右拼接得到 \(t(s)\) 。
在取子串前,可以执行一种操作:交换 \(s\) 中的两个不同位置的字符。
问最少需要执行多少次操作,才能使得 \(t(s)\) 是所有可能的结果中字典序最大的。
题解
知识点:并查集,树状数组,贪心。
显然,子串靠前的,位置在子串中靠前的,优先级更大。因此,按子串顺序,子串内从左到右,给 \(s\) 的位置规定排名 \(rk\) 。
排名中可能会遇到之前已经排名过的位置,这些位置的排名是不需要改变的,我们需要跳过它们。为了保证复杂度,可以用并查集实现跳转,当然也可以用 set 。
接下来,我们要尽可能把 \(1\) 交换到排名靠前的位置,因此我们需要知道 \(1\) 的总数 \(cnt\) ,以及排名前 \(cnt\) 个位置的 \(1\) 个数 \(sum[1,cnt]\) ,交换次数就是 \(cnt - sum[1,cnt]\) 。
时间复杂度 \(O((n+q)\log n)\)
空间复杂度 \(O(n)\)
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T>
class Fenwick {
int n;
vector<T> node;
public:
Fenwick(int _n = 0) { init(_n); }
void init(int _n) {
n = _n;
node.assign(n + 1, T());
}
void update(int x, T val) { for (int i = x;i <= n;i += i & -i) node[i] += val; }
T query(int x) {
T ans = T();
for (int i = x;i >= 1;i -= i & -i) ans += node[i];
return ans;
}
T query(int l, int r) {
T ans = T();
ans += query(r);
ans -= query(l - 1);
return ans;
}
int lower_bound(T val) {
int pos = 0;
for (int i = 1 << __lg(n); i; i >>= 1) {
if (pos + i <= n && node[pos + i] < val) {
pos += i;
val -= node[pos];
}
}
return pos + 1;
}
int upper_bound(T val) {
int pos = 0;
for (int i = 1 << __lg(n); i; i >>= 1) {
if (pos + i <= n && node[pos + i] <= val) {
pos += i;
val -= node[pos];
}
}
return pos + 1;
}
};
struct DSU {
vector<int> fa;
DSU(int n = 0) { init(n); }
void init(int n) {
fa.assign(n + 1, 0);
iota(fa.begin(), fa.end(), 0);
}
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
bool same(int x, int y) { return find(x) == find(y); }
void merge(int x, int y) { fa[find(x)] = find(y); }
};
int idx;
int rk[200007];
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, m, q;
cin >> n >> m >> q;
string s;
cin >> s;
s = "?" + s;
int cnt = count(s.begin() + 1, s.end(), '1');
Fenwick<int> fw(n);
DSU dsu(n + 1);
for (int i = 1;i <= m;i++) {
int l, r;
cin >> l >> r;
for (int j = dsu.find(l);j <= r;j = dsu.find(j)) {
rk[j] = ++idx;
if (s[j] == '1') fw.update(rk[j], 1);
dsu.merge(j, j + 1);
}
}
while (q--) {
int x;
cin >> x;
if (s[x] == '0') {
s[x] = '1';
cnt++;
if (rk[x]) fw.update(rk[x], 1);
}
else {
s[x] = '0';
cnt--;
if (rk[x]) fw.update(rk[x], -1);
}
cout << min(cnt, idx) - fw.query(min(cnt, idx)) << '\n';
}
return 0;
}
Codeforces Round #882 (Div. 2) A-D的更多相关文章
- Codeforces Round #366 (Div. 2) ABC
Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...
- Codeforces Round #354 (Div. 2) ABCD
Codeforces Round #354 (Div. 2) Problems # Name A Nicholas and Permutation standard input/out ...
- Codeforces Round #368 (Div. 2)
直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...
- cf之路,1,Codeforces Round #345 (Div. 2)
cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅..... ...
- Codeforces Round #279 (Div. 2) ABCDE
Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name A Team Olympiad standard input/outpu ...
- Codeforces Round #262 (Div. 2) 1003
Codeforces Round #262 (Div. 2) 1003 C. Present time limit per test 2 seconds memory limit per test 2 ...
- Codeforces Round #262 (Div. 2) 1004
Codeforces Round #262 (Div. 2) 1004 D. Little Victor and Set time limit per test 1 second memory lim ...
- Codeforces Round #371 (Div. 1)
A: 题目大意: 在一个multiset中要求支持3种操作: 1.增加一个数 2.删去一个数 3.给出一个01序列,问multiset中有多少这样的数,把它的十进制表示中的奇数改成1,偶数改成0后和给 ...
- Codeforces Round #268 (Div. 2) ABCD
CF469 Codeforces Round #268 (Div. 2) http://codeforces.com/contest/469 开学了,时间少,水题就不写题解了,不水的题也不写这么详细了 ...
- 贪心+模拟 Codeforces Round #288 (Div. 2) C. Anya and Ghosts
题目传送门 /* 贪心 + 模拟:首先,如果蜡烛的燃烧时间小于最少需要点燃的蜡烛数一定是-1(蜡烛是1秒点一支), num[g[i]]记录每个鬼访问时已点燃的蜡烛数,若不够,tmp为还需要的蜡烛数, ...
随机推荐
- DG:switchover切换操作
问题描述:我们配置DG的目的就是为了在主库出现故障时,备库能够提供服务,保证业务的正常运行,switchover是用户有计划的进行停机切换,能够保证不丢失数据,我记录一下我进行switchover中的 ...
- Mybatis-Plus如何自定义SQL注入器?
有关Mybatis-Plus常用功能之前有做过一篇总结: MyBatisPlus常用功能总结!(附项目示例) 一.什么是SQL注入器 我们在使用Mybatis-Plus时,dao层都会去继承BaseM ...
- 【SSM项目】尚筹网(四)JWT以及基于拦截器的前后端分离登录验证
引入JWT前后端交互 JsonWebToken(JWT),是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准.JWT就是一段字符串,分为三段[头部.载荷.签证]. 1 后端配置 1.1 ...
- Python中的print()语句
Python中print()语句的相关使用 介绍 print()函数可以将输出的信息打印出来,即发送给标准输出流.Python中可以直接使用print()函数,将信息展示在控制台 基本使用方法 输出数 ...
- mongodb使用自带命令工具导出导入数据
记录 mongo 数据库用原生自带的命令工具使用 json 文件方式进行导入.导出的操作! 在一次数据更新中,同事把老数据进行了清空操作,但是新的逻辑数据由于某种原因(好像是她的电脑中病毒了),一直无 ...
- 特性介绍 | MySQL 测试框架 MTR 系列教程(二):进阶篇 - 内存/线程/代码覆盖率/单元/压力测试
作者:卢文双 资深数据库内核研发 序言: 以前对 MySQL 测试框架 MTR 的使用,主要集中于 SQL 正确性验证.近期由于工作需要,深入了解了 MTR 的方方面面,发现 MTR 的能力不仅限于此 ...
- #Python 利用pandas 合并csv/xlsx文件
上次我们分享了利用powerquery来合并文件进行数据分析,但是Pq有一部分局限性,在现实工作中,我们往往需要合并多个文件去处理数据, 如果面对20个甚至更多的文件,pq中的每一步的步骤都会去读取每 ...
- #Powerbi 利用视觉对象着色地图,制作数据地图
日常工作中,有时我们会遇到需要地图来展示我们的数据场景,利用POWERBI,我们可以快速的制作自己的业务地图. Powerbi自带了三大地图,今天我们用到的是形状地图. 步骤讲解: 第一步:下载对应的 ...
- 2023-03-25:若两个正整数的和为素数,则这两个正整数称之为“素数伴侣“。 给定N(偶数)个正整数中挑选出若干对,组成“素数伴侣“, 例如有4个正整数:2,5,6,13, 如果将5和6分为一组的
2023-03-25:若两个正整数的和为素数,则这两个正整数称之为"素数伴侣". 给定N(偶数)个正整数中挑选出若干对,组成"素数伴侣", 例如有4个正整数:2 ...
- 2022-05-03:Alice 和 Bob 再次设计了一款新的石子游戏。现有一行 n 个石子,每个石子都有一个关联的数字表示它的价值。给你一个整数数组 stones ,其中 stones[i] 是第
2022-05-03:Alice 和 Bob 再次设计了一款新的石子游戏.现有一行 n 个石子,每个石子都有一个关联的数字表示它的价值.给你一个整数数组 stones ,其中 stones[i] 是第 ...