Educational Codeforces Round 87 (Rated for Div. 2)
还是视频题解。
感觉E还是一个挺综合的题,涉及到二分图、dp、树上的相关内容。质量还是挺不错的。其它的应该在视频里说得比较清楚。
upd:一开始E被hack了,原因是找环时用的dfn,但dfn在链上不一定连续,直接改为用深度就好了。。
这里D题赛中是直接两个log莽过去的,但其实可以只有一个log,就我所知有两种做法,一种就是直接在权值线段树上搞,另外一种是二分。二分的话直接二分是否存在\(\leq mid\)的数,这样其实可以直接\(O(n)\)进行check的。
D还可以直接利用树状数组来找第\(k\)大的值,原理是我们只需要找到一个最大的\(x\),满足\(\sum_{i=1}^x cnt_i\leq k\),那么\(x+1\)便是答案。因为树状数组\(lowbit\)的特殊性质,假设当前\(lowbit=2^t\),也就是管辖了\(2^t\)位,我们只需要看看这些的\(sum\)加起来是不是超过\(k\)就行。
细节见代码吧。。确定\(x\)因为我们是从高位往低位确定,所以和一般的查询时反着来的:
D O(nlogn)
/*
* Author: heyuhhh
* Created Time: 2020/5/18 22:31:33
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = (1 << 20) + 5;
const int MAX = (1 << 20);
int n, q;
struct BIT {
int c[N];
int lowbit(int x) {
return x & (-x);
}
void add(int x, int val) {
for (;x < N; x += lowbit(x)) {
c[x] += val;
}
}
int kth(int k) {
int p = 0;
for (int i = MAX >> 1; i; i >>= 1) {
if (c[p + i] < k) {
k -= c[p + i];
p += i;
}
}
return p + 1;
}
}bit;
void run() {
cin >> n >> q;
for (int i = 1; i <= n; i++) {
int x; cin >> x;
bit.add(x, 1);
}
for (int i = 1; i <= q; i++) {
int k; cin >> k;
if (k > 0) {
bit.add(k, 1);
} else {
int t = bit.kth(-k);
bit.add(t, -1);
}
}
int t = bit.kth(1);
if (t == MAX) {
cout << 0 << '\n';
} else {
cout << t << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
代码如下:
A. Alarm Clock
/*
* Author: heyuhhh
* Created Time: 2020/5/17 17:22:46
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
void run() {
int a, b, c, d; cin >> a >> b >> c >> d;
if (a <= b) {
cout << b << '\n';
return;
}
if (c <= d) {
cout << -1 << '\n';
return;
}
int t = c - d;
a -= b;
int tot = (a + t - 1) / t;
ll ans = 1ll * tot * c + b;
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T; while(T--)
run();
return 0;
}
B. Ternary String
/*
* Author: heyuhhh
* Created Time: 2020/5/17 17:31:08
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 2e5 + 5;
char s[N];
int last[N][4];
void run() {
cin >> (s + 1);
int n = strlen(s + 1);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= 3; j++) {
last[i][j] = last[i - 1][j];
}
last[i][s[i] - '0'] = i;
}
int ans = INF;
for (int i = 3; i <= n; i++) {
if (s[i] == '1') {
int p1 = last[i][2], p2 = last[i][3];
int p = min(p1, p2);
if (p) ans = min(ans, i - p + 1);
} else if(s[i] == '2') {
int p1 = last[i][1], p2 = last[i][3];
int p = min(p1, p2);
if (p) ans = min(ans, i - p + 1);
} else {
int p1 = last[i][1], p2 = last[i][2];
int p = min(p1, p2);
if (p) ans = min(ans, i - p + 1);
}
}
if (ans == INF) ans = 0;
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T; while(T--)
run();
return 0;
}
C1. Simple Polygon Embedding
/*
* Author: heyuhhh
* Created Time: 2020/5/17 17:55:24
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
const double pi = 3.14159265;
void run() {
int n; cin >> n;
double a = 1.0 * (2 * n - 2) * 180 / n / 4;
double ans = tan(a * pi / 180);
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T; while(T--)
run();
return 0;
}
C2. Not So Simple Polygon Embedding
/*
* Author: heyuhhh
* Created Time: 2020/5/18 10:20:46
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
const double pi = 3.1415926;
void run() {
int n; cin >> n;
double ans = cos(pi / 4 / n) / sin(pi / 2 / n);
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T; while(T--)
run();
return 0;
}
D. Multiset
/*
* Author: heyuhhh
* Created Time: 2020/5/17 18:20:26
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e6 + 5;
struct BIT {
int c[N];
int lowbit(int x) {
return x & (-x);
}
void add(int x, int v = 1) {
for (; x < N; x += lowbit(x)) {
c[x] += v;
}
}
int query(int x) {
int res = 0;
for (;x ; x -= lowbit(x)) {
res += c[x];
}
return res;
}
}bit;
void run() {
int n, q; cin >> n >> q;
for (int i = 1; i <= n; i++) {
int x; cin >> x;
bit.add(x);
}
while (q--) {
int k; cin >> k;
if (k > 0) {
bit.add(k);
} else {
k = -k;
int l = 1, r = N, mid;
while (l < r) {
mid = (l + r) >> 1;
if (bit.query(mid) >= k) r = mid;
else l = mid + 1;
}
bit.add(r, -1);
}
}
int t = bit.query(N - 1);
if (t == 0) {
cout << 0 << '\n';
} else {
for (int i = 1; i < N; i++) {
if (bit.query(i) - bit.query(i - 1) > 0) {
cout << i << '\n';
break;
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
E. Graph Coloring
/*
* Author: heyuhhh
* Created Time: 2020/5/17 19:07:00
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << std::endl; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) {
for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
#define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 5000 + 5, M = 1e5 + 5;
int n, m;
int a[3];
struct Edge {
int v, next;
}e[M << 1];
int head[N], tot;
void adde(int u, int v) {
e[tot].v = v; e[tot].next = head[u]; head[u] = tot++;
}
int dfn[N], T;
int deep[N];
vector <int> v;
void dfs(int u, int fa) {
v.push_back(u);
deep[u] = deep[fa] + 1;
dfn[u] = ++T;
for (int i = head[u]; i != -1; i = e[i].next) {
int v = e[i].v;
if (v == fa) continue;
if (dfn[v]) {
if ((deep[u] - deep[v] + 1) & 1) {
cout << "NO" << '\n';
exit(0);
}
} else {
dfs(v, u);
}
}
}
int ans[N];
pii dp[N][N];
void run() {
cin >> n >> m;
memset(head, -1, sizeof(head));
for (int i = 0; i < 3; i++) cin >> a[i];
for (int i = 1; i <= m; i++) {
int u, v; cin >> u >> v;
adde(u, v), adde(v, u);
}
vector <vector<int>> odd, even;
for (int i = 1; i <= n; i++) if (!dfn[i]) {
v.clear();
dfs(i, 0);
vector <int> v1, v2;
for (auto it : v) {
if (deep[it] & 1) v1.push_back(it);
else v2.push_back(it);
}
odd.push_back(v1);
even.push_back(v2);
}
int blocks = sz(odd);
memset(dp, -1, sizeof(dp));
dp[0][sz(odd[0])] = MP(0, 0);
dp[0][sz(even[0])] = MP(0, 1);
for (int i = 0; i < blocks - 1; i++) {
for (int j = 0; j <= a[1]; j++) if (dp[i][j].fi >= 0) {
if (j + sz(odd[i + 1]) <= a[1]) {
dp[i + 1][j + sz(odd[i + 1])] = MP(j, 0);
}
if (j + sz(even[i + 1]) <= a[1]) {
dp[i + 1][j + sz(even[i + 1])] = MP(j, 1);
}
}
}
if (dp[blocks - 1][a[1]].fi >= 0) {
cout << "YES" << '\n';
pii now = dp[blocks - 1][a[1]];
int t = blocks - 1;
while (t >= 0) {
if (now.se == 0) {
for (auto it : odd[t]) {
ans[it] = 2;
}
for (auto it : even[t]) {
if (a[0] > 0) {
ans[it] = 1;
--a[0];
} else {
ans[it] = 3;
}
}
} else {
for (auto it : even[t]) {
ans[it] = 2;
}
for (auto it : odd[t]) {
if (a[0] > 0) {
ans[it] = 1;
--a[0];
} else {
ans[it] = 3;
}
}
}
if (t == 0) break;
--t;
now = dp[t][now.fi];
}
for (int i = 1; i <= n; i++) {
cout << ans[i];
}
cout << '\n';
} else {
cout << "NO" << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
重要的是自信,一旦有了自信,人就会赢得一切。