CF 990 Educational Codeforces Round 45
既然补了就简单记录一下。
感觉还算有一点营养。
官方题解传送门:点我
A Commentary Boxes
对拆掉$n \mod m$个和新建$m - (n \mod m)$求个最小。
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- using namespace std;
- typedef long long ll;
- int main() {
- ll n, m, a, b, r;
- scanf("%lld%lld%lld%lld", &n, &m, &a, &b);
- r = n % m;
- printf("%lld\n", min(b * r, (m - r) * a));
- return ;
- }
A
B Micro-World
对所有数排序,从小到大扫,能吃就吃。
一个细菌如果不被刚好比它大的那个吃掉,那么再大一点的也不能吃掉。
注意到相同的数可能处理起来有一点问题,像我这种懒人就直接开个$map$当平衡树用。
- #include <cstdio>
- #include <cstring>
- #include <map>
- using namespace std;
- int n, k;
- map <int, int> mp;
- template <typename T>
- inline void read(T &X) {
- X = ; char ch = ; T op = ;
- for (; ch > ''|| ch < ''; ch = getchar())
- if (ch == '-') op = -;
- for (; ch >= '' && ch <= ''; ch = getchar())
- X = (X << ) + (X << ) + ch - ;
- X *= op;
- }
- int main() {
- read(n), read(k);
- for (int v, i = ; i <= n; i++) {
- read(v);
- ++mp[v];
- }
- map <int, int> :: iterator lst = mp.begin(), now = mp.begin();
- ++now;
- int ans = ;
- for (; now != mp.end(); ++lst, ++now)
- if (now -> first <= lst -> first + k) ans += lst -> second;
- printf("%d\n", n - ans);
- return ;
- }
B
C Bracket Sequences Concatenation Problem
话说最近的几场中有类似的题目啊。
一个括号序列在自身匹配完之后一定能表示成若干个右括号$+$若干个左括号(比如$))))(((($)的形式,两个括号序列接起来能匹配的充要条件是:
1、前面的那个没有多余的右括号。
2、后面的那个没有多余的左括号。
3、前面的左括号和后面的右括号个数相同。
开个$map$正反扫一扫,注意不要忘记计算一个括号序列自身可能的贡献。
- #include <cstdio>
- #include <cstring>
- #include <map>
- #include <iostream>
- using namespace std;
- typedef pair <int, int> pin;
- typedef long long ll;
- const int N = 3e5 + ;
- int n;
- pin a[N];
- char s[N];
- map <int, int> mp;
- int main() {
- scanf("%d", &n);
- for (int i = ; i <= n; i++) {
- scanf("%s", s + );
- int len = strlen(s + ), top = ;
- for (int j = ; j <= len; j++) {
- if (s[j] == '(') ++top;
- else {
- if (top) --top;
- else ++a[i].first;
- }
- }
- if (top != ) a[i].second += top;
- }
- ll ans = ;
- for (int i = ; i <= n; i++) {
- if (a[i].second == ) ans += mp[a[i].first];
- if (a[i].first == ) ++mp[a[i].second];
- }
- mp.clear();
- for (int i = n; i >= ; i--) {
- if (a[i].second == ) ans += mp[a[i].first];
- if (a[i].first == ) ++mp[a[i].second];
- }
- for (int i = ; i <= n; i++)
- if (a[i].first == && a[i].second == ) ++ans;
- printf("%lld\n", ans);
- return ;
- }
C
D Graph And Its Complement
我觉得这是这场最有趣的一道题。
做出这个首先需要发现一条性质,$n, a, b$一定需要满足$a == 1$或者$b == 1$的形式才可能有解。
可能的意思是说在$a == 1$并且$b == 1$并且$n == 2 || n == 3$的时候无解。
假设原图有超过$1$个连通块,那么对于任意两个联通块来说,取补集之后都会有一条边相连,所以补图一定只有一个连通块。
如果$b$为$1$并且$a$不为$1$可以$swap$过来然后输出补图。
这样子把$1$到$n - a + 1$连成一条链就好了。
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- using namespace std;
- const int N = ;
- int n, a, b;
- bool ans[N][N];
- int main() {
- scanf("%d%d%d", &n, &a, &b);
- if (a != && b != ) return puts("NO"), ;
- if (a == && b == ) {
- if (n == || n == ) return puts("NO"), ;
- for (int i = ; i < n; i++) ans[i][i + ] = ans[i + ][i] = ;
- puts("YES");
- for (int i = ; i <= n; i++, putchar('\n'))
- for (int j = ; j <= n; j++)
- putchar(ans[i][j] + '');
- return ;
- }
- bool flag = ;
- if (a == ) swap(a, b), flag = ;
- if (flag) memset(ans, , sizeof(ans));
- for (int i = ; i <= n - a; i++) ans[i][i + ] ^= , ans[i + ][i] ^= ;
- puts("YES");
- for (int i = ; i <= n; i++, putchar('\n'))
- for (int j = ; j <= n; j++) {
- if (i == j) putchar('');
- else putchar(ans[i][j] + '');
- }
- return ;
- }
D
E Post Lamps
这题我纠结了很长时间的第一个样例,因为怎么玩都有比样例输出更好的答案,直到我在$announcement$里面发现了这样一句话:
感觉无话可说……
先考虑没有“不能放”的限制的时候怎么做,对于每一个亮度$k$,贪心地把它放在$0, k, 2k, \cdots$直到大于等于$n$。
现在加入限制条件,考虑如果在跳的时候遇到了一个障碍,就尝试在这个障碍前面最近的一个不是障碍的位置放灯,如果这样还是不可以照亮它,那么直接无解。
障碍在$0$的时候可以直接无解。
可以用一个并查集,遇到障碍就把父指针指向前一个位置,这个并查集可以路径压缩。
注意到这个复杂度其实是一个调和级数,虽然并不是特别严格,但是根本跑不满。
应该比$D$简单吧。
- #include <cstdio>
- #include <cstring>
- using namespace std;
- typedef long long ll;
- const int N = 1e6 + ;
- const ll inf = 1LL << ;
- int n, m, k, ufs[N];
- ll a[N];
- bool b[N];
- template <typename T>
- inline void read(T &X) {
- X = ; char ch = ; T op = ;
- for (; ch > ''|| ch < ''; ch = getchar())
- if (ch == '-') op = -;
- for (; ch >= '' && ch <= ''; ch = getchar())
- X = (X << ) + (X << ) + ch - ;
- X *= op;
- }
- template <typename T>
- inline void chkMin(T &x, T y) {
- if (y < x) x = y;
- }
- int find(int x) {
- return ufs[x] == x ? x : ufs[x] = find(ufs[x]);
- }
- int main() {
- read(n), read(m), read(k);
- for (int i = ; i <= n; i++) ufs[i] = i;
- for (int pos, i = ; i <= m; i++) {
- read(pos);
- if (pos == ) return puts("-1"), ;
- b[pos] = ;
- ufs[pos] = pos - ;
- }
- b[n] = , ufs[n] = n - ;
- for (int i = ; i <= k; i++) read(a[i]);
- ll ans = inf;
- for (int i = ; i <= k; i++) {
- int cnt = ; ll res = ;
- for (int j = ; j < n; j += i) {
- if (!b[j]) ++cnt;
- else {
- int pos = find(ufs[j]);
- if (j - pos < i) ++cnt, j = pos;
- else {
- res = inf;
- break;
- }
- }
- }
- if (res != inf) res = 1LL * cnt * a[i];
- chkMin(ans, res);
- }
- printf("%I64d\n", ans == inf ? - : ans);
- return ;
- }
E
F Flow Control
虽然网络流已经差不多忘得一干二净了,但是流量守恒这一点还是能记住手玩出来的。
先把所有的$s_i$求和,如果不为$0$一定不合法。
注意到当有环的时候有一些边可以随便流,等价于就算这些边不存在(流量为$0$)也能出解。
所以做一棵生成树就好了,不在生成树中的边流量输出$0$。
- #include <cstdio>
- #include <cstring>
- #include <iostream>
- using namespace std;
- typedef long long ll;
- typedef pair <int, int> pin;
- const int N = 2e5 + ;
- int n, m, tot = , head[N], ufs[N], dep[N];
- ll a[N], sum[N];
- bool vis[N];
- pin pat[N];
- struct Edge {
- int to, nxt;
- } e[N << ];
- inline void add(int from, int to) {
- e[++tot].to = to;
- e[tot].nxt = head[from];
- head[from] = tot;
- }
- template <typename T>
- inline void read(T &X) {
- X = ; char ch = ; T op = ;
- for (; ch > ''|| ch < ''; ch = getchar())
- if (ch == '-') op = -;
- for (; ch >= '' && ch <= ''; ch = getchar())
- X = (X << ) + (X << ) + ch - ;
- X *= op;
- }
- int find(int x) {
- return ufs[x] == x ? x : ufs[x] = find(ufs[x]);
- }
- inline bool merge(int x, int y) {
- int fx = find(x), fy = find(y);
- if (fx == fy) return ;
- ufs[fx] = fy;
- return ;
- }
- inline bool chk() {
- ll tmp = ;
- for (int i = ; i <= n; i++) tmp += a[i];
- return (!tmp);
- }
- void dfs(int x, int fat, int depth) {
- dep[x] = depth, sum[x] = a[x];
- for (int i = head[x]; i; i = e[i].nxt) {
- int y = e[i].to;
- if (y == fat) continue;
- dfs(y, x, depth + );
- sum[x] += sum[y];
- }
- }
- int main() {
- read(n);
- for (int i = ; i <= n; i++) {
- read(a[i]);
- ufs[i] = i;
- }
- read(m);
- for (int x, y, i = ; i <= m; i++) {
- read(x), read(y);
- pat[i].first = x, pat[i].second = y;
- if (!merge(x, y)) continue;
- vis[i] = ;
- add(x, y), add(y, x);
- }
- if (!chk()) return puts("Impossible"), ;
- dfs(, , );
- puts("Possible");
- for (int i = ; i <= m; i++) {
- if (vis[i])
- printf("%lld\n", dep[pat[i].first] < dep[pat[i].second] ? sum[pat[i].second] : -sum[pat[i].first]);
- else puts("");
- }
- return ;
- }
F
G GCD Counting
因为统计的时候复杂度是只和$gcd$的个数有关的,所以可以直接大力点分治,复杂度也是没问题的。
但是点分治真的写不对这样太无脑了,考虑正解提到的稍微有一点技术含量的做法。
用$h(i)$表示树上能被$i$整除的路径的数量,注意到在树上一定是若干个满足条件的联通块选点之后求和。
一个$siz$为$n$的连通块的贡献是$\frac{n(n + 1)}{2}$。
那么最后的答案
$$ans_x = \sum_{i = x}^{\left \lfloor \frac{n}{x} \right \rfloor}\mu(i)h(xi)$$
我选择用一个并查集合并一下。
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- #include <vector>
- using namespace std;
- typedef long long ll;
- const int N = 2e5 + ;
- const int Maxn = 2e5;
- int n, a[N], tot = , head[N], fa[N];
- int pCnt = , pri[N], mu[N], ufs[N], siz[N];
- bool np[N], vis[N];
- ll ans[N], f[N];
- vector <int> h[N], vec;
- struct Edge {
- int to, nxt;
- } e[N << ];
- inline void add(int from, int to) {
- e[++tot].to = to;
- e[tot].nxt = head[from];
- head[from] = tot;
- }
- template <typename T>
- inline void read(T &X) {
- X = ; char ch = ; T op = ;
- for (; ch > ''|| ch < ''; ch = getchar())
- if (ch == '-') op = -;
- for (; ch >= '' && ch <= ''; ch = getchar())
- X = (X << ) + (X << ) + ch - ;
- X *= op;
- }
- inline void sieve() {
- mu[] = ;
- for (int i = ; i <= Maxn; i++) {
- if (!np[i])
- pri[++pCnt] = i, mu[i] = -;
- for (int j = ; j <= pCnt && pri[j] * i <= Maxn; j++) {
- np[i * pri[j]] = ;
- if (i % pri[j] == ) {
- mu[i * pri[j]] = ;
- break;
- }
- mu[i * pri[j]] = -mu[i];
- }
- }
- }
- void dfs(int x, int fat) {
- fa[x] = fat;
- for (int i = head[x]; i; i = e[i].nxt) {
- int y = e[i].to;
- if (y == fat) continue;
- dfs(y, x);
- }
- }
- int find(int x) {
- return ufs[x] == x ? x : ufs[x] = find(ufs[x]);
- }
- inline bool merge(int x, int y) {
- int fx = find(x), fy = find(y);
- if (fx == fy) return ;
- if (siz[fx] < siz[fy]) ufs[fx] = fy, siz[fy] += siz[fx];
- else ufs[fy] = fx, siz[fx] += siz[fy];
- return ;
- }
- int main() {
- sieve();
- read(n);
- for (int i = ; i <= n; i++) {
- read(a[i]);
- h[a[i]].push_back(i);
- }
- for (int x, y, i = ; i < n; i++) {
- read(x), read(y);
- add(x, y), add(y, x);
- }
- dfs(, );
- for (int i = ; i <= Maxn; i++) {
- for (int j = i; j <= Maxn; j += i)
- for (int k = ; k < (int)h[j].size(); k++) {
- int x = h[j][k];
- ufs[x] = x, siz[x] = , vis[x] = ;
- vec.push_back(x);
- }
- for (int j = ; j < (int)vec.size(); j++) {
- int x = vec[j];
- if (fa[x] && a[fa[x]] % i == ) merge(x, fa[x]);
- }
- for (int j = ; j < (int)vec.size(); j++) {
- int x = vec[j], fx = find(x);
- if (vis[fx]) continue;
- f[i] += 1LL * siz[fx] * (siz[fx] + ) / ;
- vis[fx] = ;
- }
- vec.clear();
- }
- for (int i = ; i <= Maxn; i++)
- for (int j = i; j <= Maxn; j += i)
- ans[i] += 1LL * mu[j / i] * f[j];
- for (int i = ; i <= Maxn; i++) {
- if (!ans[i]) continue;
- printf("%d %I64d\n", i, ans[i]);
- }
- return ;
- }
G
CF 990 Educational Codeforces Round 45的更多相关文章
- Educational Codeforces Round 45 (Div 2) (A~G)
目录 Codeforces 990 A.Commentary Boxes B.Micro-World C.Bracket Sequences Concatenation Problem D.Graph ...
- Educational Codeforces Round 45 (Rated for Div. 2) C、D
C. Bracket Sequences Concatenation Problem time limit per test 2 seconds memory limit per test 256 ...
- Educational Codeforces Round 45 (Rated for Div. 2) E - Post Lamps
E - Post Lamps 思路:一开始看错题,以为一个地方不能重复覆盖,我一想值这不是sb题吗,直接每个power check一下就好....复杂度nlogn 然后发现不是,这样的话,对于每个po ...
- Educational Codeforces Round 45 (Rated for Div. 2) G - GCD Counting
G - GCD Counting 思路:我猜测了一下gcd的个数不会很多,然后我就用dfs回溯的时候用map暴力合并就好啦. 终判被卡了MLE..... 需要每次清空一下子树的map... #inc ...
- Educational Codeforces Round 45 (Rated for Div. 2) F - Flow Control
F - Flow Control 给你一个有向图,要求你给每条边设置流量,使得所有点的流量符合题目给出的要求. 思路:只有在所有点的流量和为0时有解,因为增加一条边的值不会改变所有点的总流量和, 所以 ...
- Educational Codeforces Round 45 (Rated for Div. 2)
A bracket sequence is a string containing only characters "(" and ")". A regular ...
- Educational Codeforces Round 45
A. 一个小模拟 不解释 //By SiriusRen #include <bits/stdc++.h> using namespace std; long long n,m,a,b ...
- [Educational Codeforces Round 16]E. Generate a String
[Educational Codeforces Round 16]E. Generate a String 试题描述 zscoder wants to generate an input file f ...
- [Educational Codeforces Round 16]D. Two Arithmetic Progressions
[Educational Codeforces Round 16]D. Two Arithmetic Progressions 试题描述 You are given two arithmetic pr ...
随机推荐
- emmc boot_config文件不存在
/******************************************************************************* * emmc boot_config文 ...
- python3 openpyxl基本操作
#coding:utf-8 import xlrd import xlwt # 读写2007 excel import openpyxl import sys #读取设备sn # def readSN ...
- 浅谈iOS学习之路(转)
转眼学习iOS已经快两年的时间了,这个路上有挫折也有喜悦,一步步走过来发现这个过程是我这一辈子的财富,我以前的老大总是对我说,年轻就是最大的资本(本人91年),现在才算是慢慢的体会到,反观自己走过的这 ...
- ajax请求返回Json字符串运用highcharts数据图表展现数据
[1].[图片] Json字符串和highcharts数据图表展现.jpg 跳至 [1] code=26754#44745" rel="nofollow"> [2] ...
- Spring集成Mybatis(Dao方式开发)
Spring整成Mybatis注意事项: 1. 关键jar包不能少 2.可以单独整理好Mybatis框架,测试无误再集成Spring 3.集成时,参数级别的细节可以选择忽略,但思路必须清晰 代码如下 ...
- hadoop YARN配置参数剖析—MapReduce相关参数
MapReduce相关配置参数分为两部分,分别是JobHistory Server和应用程序参数,Job History可运行在一个独立节点上,而应用程序参数则可存放在mapred-site.xml中 ...
- bzoj 5020(洛谷4546) [THUWC 2017]在美妙的数学王国中畅游——LCT+泰勒展开
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=5020 https://www.luogu.org/problemnew/show/P4546 ...
- 打印进度条——(progress bar才是专业的)
# 打印进度条——(progress bar是专业的) import time for i in range(0,101,2): time.sleep(0.1) char_num = i//2 #打印 ...
- Django 组件-分页器
Django的分页器(paginator) view from django.shortcuts import render,HttpResponse # Create your views here ...
- HDU 1358 Period (kmp判断循环子串)
Period Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Submis ...