Codeforces Round #588 (Div. 2)
A. Dawid and Bags of Candies
乱搞。
Code
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
//#define Local
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 5;
int a[4];
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
#ifdef Local
freopen("../input.in", "r", stdin);
freopen("../output.out", "w", stdout);
#endif
for(int i = 0; i < 4; i++) cin >> a[i];
sort(a, a + 4);
if(a[0] + a[3] == a[1] + a[2] || a[0] + a[1] + a[2] == a[3]) cout << "YES";
else cout << "NO";
return 0;
}
B. Ania and Minimizing
贪心。
Code
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
//#define Local
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 2e5 + 5;
int n, k;
char s[N];
void run() {
cin >> s + 1;
if(n == 1 && k >= 1) {
cout << 0 << '\n'; return;
}
for(int i = 1; i <= n; i++) {
if(i == 1) {
if(s[i] > '1' && k) {
s[i] = '1'; --k;
}
} else {
if(k && s[i] != '0') {
s[i] = '0'; --k;
}
}
}
cout << s + 1 << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
#ifdef Local
freopen("../input.in", "r", stdin);
freopen("../output.out", "w", stdout);
#endif
while(cin >> n >> k) run();
return 0;
}
C. Anadi and Domino
题意:
存在一张图有\(n,n\leq 7\)个点,现在要给他们染上\(1\)~\(6\)的颜色。最后问怎样染色,能够使得\((c_1,c_2)\)这样的对数最多(不计算重复,不考虑顺序,\(c_1,c_2\)表示颜色)。
思路:
一开始想的是随机乱搞一发,结果出了不知道什么错wa了一个点= =
其实直接\(dfs\)就行了,复杂度不会超。
Code
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
//#define Local
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 10;
int n, m;
int ans, res;
vector <int> g[N];
int c[N];
bool chk[N][N];
void dfs(int x) {
if(x == n + 1) {
res = 0;
for(int i = 1; i <= n; i++) {
for(auto it : g[i]) {
chk[c[i]][c[it]] = 1;
}
}
for(int i = 1; i <= 6; i++) {
for(int j = i; j <= 6; j++) {
if(chk[i][j]) {
++res;
chk[i][j] = 0;
}
}
}
ans = max(ans, res);
return;
}
for(int i = 1; i <= 6; i++) {
c[x] = i;
dfs(x + 1);
}
}
void run() {
for(int i = 1; i <= m; i++) {
int u, v; cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1);
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
#ifdef Local
freopen("../input.in", "r", stdin);
freopen("../output.out", "w", stdout);
#endif
while(cin >> n >> m) run();
return 0;
}
D. Marcin and Training Camp
题意:
先有\(n\)个人,每个人有两个属性:\(a,b\)。其中\(a\)的含义是,当前这个人会一些技能,技能的\(id\)就为\(a\)里面二进制\(1\)的位置。
\(i\)看不起\(j\),当且仅当\(i\)会一项\(j\)不会的技能。
现在要选择一些人出来作为一支团队,要求不存在一个人看不起其它所有人并且\(b\)的和最大。
思路:
题意不好描述啊感觉= =
首先可以发现一个比较显然的结论:
- 团队中最大的\(a\)值至少有两个。
因为要\(b\)和最大,所以有推论:
- 若存在多个人的\(a\)相同,那么他们都可以选择。
处理完上面的情况,剩下的就是\(a\)只出现一次了。接下来又有一个结论:
- 一个\(a\)能够被选择,当且仅当他作为已选集合的一个子集。
如果不满足上面的条件,那么他就能够看不起其它所有人,除非有其他人\(a\)值和他相同,但这种情况已经排除了。
然后随便写写就好了。
Code
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
//#define Local
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 7006;
struct People{
ll a, b;
bool operator < (const People &A) const {
if(a == A.a) return b < A.b;
return a < A.a;
}
}p[N], t[N];
int n;
void run() {
for(int i = 1; i <= n; i++) cin >> t[i].a;
for(int i = 1; i <= n; i++) cin >> t[i].b;
sort(t + 1, t + n + 1);
ll ans = 0;
int tot = 0;
vector <ll> S;
for(int i = 1, j; i <= n; i = j) {
ll tmp = 0, cnt = 0;
j = i;
while(j <= n && t[i].a == t[j].a) {
tmp += t[j].b;
++cnt; ++j;
}
if(cnt > 1) {
ans += tmp;
S.push_back(t[i].a);
} else {
p[++tot] = t[i];
}
}
for(int i = 1; i <= tot; i++) {
int ok = 0;
for(auto it : S) {
if((p[i].a & it) == p[i].a) ok = 1;
}
if(ok) {
ans += p[i].b;
// S.push_back(p[i].a);
}
}
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
#ifdef Local
freopen("../input.in", "r", stdin);
freopen("../output.out", "w", stdout);
#endif
while(cin >> n) run();
return 0;
}
E. Kamil and Making a Stream
题意:
给出一颗树,每个结点都有其权值,先求所有链的\(gcd\)的和。
思路:
- 比较直接的想法就是\(O(n^2)\)的暴力,对于每个点\(v\),找到其所有的祖先\(u\),计算\(gcd\)。
- 稍微改进一下,不用找到所有的祖先,只需要找到其父亲与所有祖先的\(gcd\)值就行,但复杂度还是没有变。
- 发现\(gcd\)的个数很少,大概为\(\log_{2}a[v]\)个,因为每个\(gcd\)都为\(a[v]\)因子。所以直接用一个\(map\)来存一下出现次数就行了。
似乎这里\(map\)的\(log\)和\(gcd\)的\(log\)的分开的...
Code
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
//#define Local
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 5, MOD = 1e9 + 7;
int n;
ll a[N];
vector <int> g[N];
unordered_map <ll, int> mp[N];
ll ans;
void dfs(int u, int fa) {
for(auto it : mp[fa]) {
ll now = __gcd(it.fi, a[u]);
mp[u][now] += it.se;
}
++mp[u][a[u]];
for(auto it : mp[u]) {
ans = (ans + it.fi * it.se % MOD) % MOD;
}
for(auto v : g[u]) {
if(v != fa) dfs(v, u);
}
}
void run() {
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i < n; i++) {
int u, v; cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1, 0);
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
#ifdef Local
freopen("../input.in", "r", stdin);
freopen("../output.out", "w", stdout);
#endif
while(cin >> n) run();
return 0;
}
F. Konrad and Company Evaluation
题意:
给出一个\(n\)个点\(m\)条边的有向图,现在有\(q\)次操作,每次可以选择一个点,然后将它所有的入边反转。
问每次操作过后形成的“三元环”数量,这里“三元环”的定义为对于点\(a,b,c\),有\(a->b->c\),那么这就算作一个。
\(n,m,q\leq 10^5\)。
思路:
- 统计三元环时,易知一个点的贡献为\(out[u]*in[u]\),相当于枚举中点。
问题在于每次如何翻转边并且快速统计答案。然后题解就是暴力翻转就行了...
下面简略证明一下:
- 我们按照每个点的度从大到小排序,并且以度数为\(\sqrt{2m}\)划分界限,左边为“大点”,右边为“小点”。
- 易知左边点的个数不会超过\(\sqrt{2m}\)个,而右边点的度数不会超过\(\sqrt{2m}\)。
- 现在将所有边分为三类:在“大点”间的,在“小点”间的,以及跨过中线的,然后依次分析:
- 显然每次对“小点”操作不会超过\(\sqrt{2m}\);
- 对于跨过中间的,我们先消耗一定复杂度让其全部指向“小点”,易知复杂度不超过\(O(m)\)。
- 那么每次对“大点”操作,第一类复杂度不会超过\(\sqrt{2m}\)(因为个数只有那么多),对于第三类边,只有可能一开始已经翻转过,那么这类边每次操作的复杂度最高为\(O(T)\),\(T\)表示当前时间。所以对于一个“大点”而言,操作一次的最高复杂度为\(O(q+\sqrt{2m})\),最多操作\(\sqrt{2m}\)次。
* 综上,总的复杂度为$O(q\sqrt{2m}+m)$的样子。
然后暴力就行啦,感觉证明的思想核心还是对度数进行分块然后来分析,挺巧妙的~其实简单点想就是,对于每个点只有可能第一次翻转复杂度较高,后面翻转就跟时间有关了,因为每次翻转对于一个点入度最多增加\(1\)。
代码很简单:
Code
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
//#define Local
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 5;
int n, m;
vector <int> in[N];
int d[N];
void run() {
for(int i = 1; i <= m; i++) {
int u, v; cin >> u >> v;
if(u > v) swap(u, v);
++d[u], ++d[v];
in[u].push_back(v);
}
ll ans = 0;
for(int i = 1; i <= n; i++) ans += 1ll * (d[i] - sz(in[i])) * sz(in[i]);
int q; cin >> q;
while(q--) {
cout << ans << '\n';
int x; cin >> x;
ans -= 1ll * (d[x] - sz(in[x])) * sz(in[x]);
for(auto v : in[x]) {
ans -= 1ll * (d[v] - sz(in[v])) * sz(in[v]);
in[v].push_back(x);
ans += 1ll * (d[v] - sz(in[v])) * sz(in[v]);
}
in[x].clear();
}
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
#ifdef Local
freopen("../input.in", "r", stdin);
freopen("../output.out", "w", stdout);
#endif
while(cin >> n >> m) run();
return 0;
}
Codeforces Round #588 (Div. 2)的更多相关文章
- Codeforces Round #588 (Div. 2)-E. Kamil and Making a Stream-求树上同一直径上两两节点之间gcd的和
Codeforces Round #588 (Div. 2)-E. Kamil and Making a Stream-求树上同一直径上两两节点之间gcd的和 [Problem Description ...
- Codeforces Round #588 (Div. 2) E. Kamil and Making a Stream(DFS)
链接: https://codeforces.com/contest/1230/problem/E 题意: Kamil likes streaming the competitive programm ...
- Codeforces Round #588 (Div. 2) D. Marcin and Training Camp(思维)
链接: https://codeforces.com/contest/1230/problem/D 题意: Marcin is a coach in his university. There are ...
- Codeforces Round #588 (Div. 2) C. Anadi and Domino(思维)
链接: https://codeforces.com/contest/1230/problem/C 题意: Anadi has a set of dominoes. Every domino has ...
- Codeforces Round #588 (Div. 2) B. Ania and Minimizing(构造)
链接: https://codeforces.com/contest/1230/problem/B 题意: Ania has a large integer S. Its decimal repres ...
- Codeforces Round #588 (Div. 2) A. Dawid and Bags of Candies
链接: https://codeforces.com/contest/1230/problem/A 题意: Dawid has four bags of candies. The i-th of th ...
- Codeforces Round #588 (Div. 1)
Contest Page 因为一些特殊的原因所以更得不是很及时-- A sol 不难发现当某个人diss其他所有人的时候就一定要被删掉. 维护一下每个人会diss多少个人,当diss的人数等于剩余人数 ...
- Codeforces Round #588 (Div. 1) 简要题解
1. 1229A Marcin and Training Camp 大意: 给定$n$个对$(a_i,b_i)$, 要求选出一个集合, 使得不存在一个元素好于集合中其他所有元素. 若$a_i$的二进制 ...
- Codeforces Round #588 (Div. 2) D题【补题ING】
思路:先找出现次数>=2数.然后在取跑所有数,需要考虑一般情况(当一个人比另一个人的ai小且他们的与运算等于小的那个人的ai那么可以知道大的那个人必定强于ai小的那个人). 则可以用位运算实现判 ...
随机推荐
- mysql存储4字节的表情包数据报异常_Emoji表情包_Incorrect string value: '\xF0\x9F\x98\x84\xF0\x9F
本文章转载自:https://www.cnblogs.com/coprince/p/7485968.html 原文如下: 问题描述:从新浪微博抓取消息保存到MySQL数据中,对应数据库字段为varch ...
- C#基础之事件(2)
在“C#基础之事件(1)”中已对事件有了一个大概,这里对事件进行更深入的学习. 本节按以下内容展开: 1.事件拥有者与事件响应者的关系: 2.事件订阅的多种写法: 3.事件的订阅和取消订阅: 4.多事 ...
- k8s的yaml说明
理解k8s里的几个概念 Kubernetes 通过各种 Controller 来管理 Pod 的生命周期.为了满足不同业务场景,Kubernetes 开发了 Deployment.ReplicaSet ...
- macOS Catalina Kernel panic 因为意外而重新启动
0x00 What's Happend? 我的 MacBook Air 在升级到 Catalina 之后,经常在休眠模式重启,随后在桌面上显示"因为意外而重新启动"的信息,以下是跟 ...
- grep的使用及正则表达式
1.常用选项: -E :开启扩展(Extend)的正则表达式. -i :忽略大小写(ignore case). -v :反过来(invert),只打印没有匹配的,而匹配的反而不打印. -n :显示行号 ...
- 池化技术(一)Druid是如何管理数据库连接的?
基于依赖程序的版本信息:druid:1.1.16 驱动程序mysql-connector-java:8.0.17 下一篇:HikariCP是如何管理数据库连接的 零.类图& ...
- 1(1).有监督 VS 无监督
对比一 : 有标签 vs 无标签 有监督机器学习又被称为“有老师的学习”,所谓的老师就是标签.有监督的过程为先通过已知的训练样本(如已知输入和对应的输出)来训练,从而得到一个最优模型,再将这个模型应用 ...
- celery beat - 心跳包
celery -A 项目名 beat -l info -S django# 启动心跳任务 celery -A 项目名 worker -l info # 启动1个worker去执行
- 最强Linux shell工具Oh My Zsh 指南
引言 笔者已经使用zsh一年多了,发现这个东东的功能太强大了.接下来,给大家推荐一下. 以下是oh-my-zsh部分功能 命令验证 在所有正在运行的shell中共享命令历史记录 拼写纠正 主题提示(A ...
- IT兄弟连 HTML5教程 CSS3揭秘 CSS常见的样式属性和值1
CSS中的样式属性比较多,经常使用的属性可以分为这么几类:字体.文本.背景.位置.边框.列表,以及其他一些样式属性.每个类中的属性都可以单独使用:如果同一个类中多个属性一起使用,还可以将它们整合为一行 ...