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;
}
posted @ 2020-05-18 13:06  heyuhhh  阅读(530)  评论(4编辑  收藏  举报