• Educational Codeforces Round 75


    Contest Info


    [Practice Link](https://codeforces.com/contest/1251)
    Solved A B C D E1 E2 F
    6/7 O O O O O O -
    • O 在比赛中通过
    • Ø 赛后通过
    • ! 尝试了但是失败了
    • - 没有尝试

    Solutions


    A. Broken Keyboard

    题意:
    有一个打字机,如果某个按键是好的,那么按下那个按键之后会在打字槽中追加一个该字符,如果是坏的则会追加两个。
    现在给出打印槽中最后的结果,问有哪些按键能确定一定是好的。

    思路:
    将连续的相同字符取出来,如果长度为奇数,那么一定能确定该字符对应的按键是好的。

    代码:

    view code
    #pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define endl "
    " 
    using namespace std;
    using db = double;
    using ll = long long;
    using ull = unsigned long long; 
    using pII = pair <int, int>;
    using pLL = pair <ll, ll>;
    constexpr int mod = 1e9 + 7;
    template <class T1, class T2> inline void chadd(T1 &x, T2 y) { x += y; while (x >= mod) x -= mod; while (x < 0) x += mod; } 
    template <class T1, class T2> inline void chmax(T1 &x, T2 y) { if (x < y) x = y; }
    template <class T1, class T2> inline void chmin(T1 &x, T2 y) { if (x > y) x = y; }
    inline int rd() { int x; cin >> x; return x; }
    template <class T> inline void rd(T &x) { cin >> x; }
    template <class T> inline void rd(vector <T> &vec) { for (auto &it : vec) cin >> it; }  
    #define dbg(x...) do { cout << "33[32;1m" << #x << " -> "; err(x); } while (0) 
    void err() { cout << "33[39;0m" << endl; } 
    template <class T, class... Ts> void err(const T& arg, const Ts&... args) { cout << arg << ' '; err(args...); }
    template <template<typename...> class T, typename t, typename... A> 
    void err(const T <t> &arg, const A&... args) { for (auto &v : arg) cout << v << ' '; err(args...); }
    inline void pt() { cout << endl; } 
    template <class T, class... Ts> void pt(const T& arg, const Ts&... args) { cout << arg << ' '; pt(args...); }
    template <template<typename...> class T, typename t, typename... A> 
    void pt(const T <t> &arg, const A&... args) { for (auto &v : arg) cout << v << ' '; pt(args...); }
    ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
    inline ll qpow(ll base, ll n) { ll res = 1; while (n) { if (n & 1) res = res * base % mod; base = base * base % mod; n >>= 1; } return res; }
    //head
    constexpr int N = 1e5 + 10;
    int n, cnt[30]; string s;
    void run() {
    	cin >> s;
    	memset(cnt, -1, sizeof cnt);
    	for (int i = 0, len = s.size(), num = 0; i <= len; ++i) {
    		if (i == len) {
    			if (num & 1) {
    				cnt[s[i - 1] - 'a'] = 1;
    			}
    		} else if (i && s[i] != s[i - 1]) {
    			if (num & 1) {
    				cnt[s[i - 1] - 'a'] = 1; 
    			}
    			num = 0;
    		}
    		++num;
    	}
    	for (int i = 0; i < 26; ++i) if (cnt[i] > 0) 
    		cout << char(i + 'a');
    	cout << endl;
    	
    }
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(nullptr); cout.tie(nullptr);
    	cout << fixed << setprecision(20);
    	int _T = rd();
    	while (_T--) run();
    	return 0;
    }
    

    B. Binary Palindromes

    题意:
    给出(n)(01)串,可以任意交换任意两个字符串的任意两个位置的字符,问最终最多能有多少回文串。

    思路:
    任意交换,只需要考虑(0)有多少个,(1)有多少个,然后根据原串长度贪心构造。

    代码:

    view code
    #pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define endl "
    " 
    using namespace std;
    using db = double;
    using ll = long long;
    using ull = unsigned long long; 
    using pII = pair <int, int>;
    using pLL = pair <ll, ll>;
    constexpr int mod = 1e9 + 7;
    template <class T1, class T2> inline void chadd(T1 &x, T2 y) { x += y; while (x >= mod) x -= mod; while (x < 0) x += mod; } 
    template <class T1, class T2> inline void chmax(T1 &x, T2 y) { if (x < y) x = y; }
    template <class T1, class T2> inline void chmin(T1 &x, T2 y) { if (x > y) x = y; }
    inline int rd() { int x; cin >> x; return x; }
    template <class T> inline void rd(T &x) { cin >> x; }
    template <class T> inline void rd(vector <T> &vec) { for (auto &it : vec) cin >> it; }  
    #define dbg(x...) do { cout << "33[32;1m" << #x << " -> "; err(x); } while (0) 
    void err() { cout << "33[39;0m" << endl; } 
    template <class T, class... Ts> void err(const T& arg, const Ts&... args) { cout << arg << ' '; err(args...); }
    template <template<typename...> class T, typename t, typename... A> 
    void err(const T <t> &arg, const A&... args) { for (auto &v : arg) cout << v << ' '; err(args...); }
    inline void pt() { cout << endl; } 
    template <class T, class... Ts> void pt(const T& arg, const Ts&... args) { cout << arg << ' '; pt(args...); }
    template <template<typename...> class T, typename t, typename... A> 
    void pt(const T <t> &arg, const A&... args) { for (auto &v : arg) cout << v << ' '; pt(args...); }
    ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
    inline ll qpow(ll base, ll n) { ll res = 1; while (n) { if (n & 1) res = res * base % mod; base = base * base % mod; n >>= 1; } return res; }
    //head
    constexpr int N = 1e5 + 10;
    int n, cnt[2], len[110]; 
    void run() {
    	n = rd();
    	cnt[0] = cnt[1] = 0;
    	for (int i = 1; i <= n; ++i) {
    		string s; cin >> s;
    		len[i] = s.size();
    		for (auto &c : s) ++cnt[c - '0'];
    	}
    	sort(len + 1, len + 1 + n);
    	int res = 0;
    	for (int i = 1; i <= n; ++i) {
    		if (len[i] & 1) {
    			if (cnt[0] & 1) {
    				--cnt[0];
    			} else if (cnt[1] & 1) {
    				--cnt[1];
    			} else if (cnt[0]) {
    				--cnt[0];
    			} else if (cnt[1]) {
    				--cnt[1];
    			} else {
    				break;
    			}
    			--len[i];
    		}
    		if (len[i] > cnt[0]) {
    			if (cnt[0] & 1) {
    				len[i] = len[i] - cnt[0] + 1;
    				cnt[0] = 1;
    			} else {
    				len[i] -= cnt[0];
    				cnt[0] = 0;
    			}
    		} else {
    			cnt[0] -= len[i];
    			len[i] = 0;
    		}
    		if (len[i] > cnt[1]) {
    			if (cnt[1] & 1) {
    				len[i] = len[i] - cnt[1] + 1;
    				cnt[1] = 1;
    			} else {
    				len[i] -= cnt[1];
    				cnt[1] = 0;
    			}
    		} else {
    			cnt[1] -= len[i];
    			len[i] = 0;
    		}
    		if (len[i]) break;
    		++res;
    	}
    	pt(res);
    }
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(nullptr); cout.tie(nullptr);
    	cout << fixed << setprecision(20);
    	int _T = rd();
    	while (_T--) run();
    	return 0;
    }
    

    C. Minimize The Integer

    题意:
    给出一个(n)位的整数,可能有前导(0),现在可以任意交换两个相邻的并且奇偶性不同的数的位置,最终结果也可以存在前导(0),问最终结果的最小值是多少。

    思路:
    显然,所有奇偶性相同的数的相对位置不变,那么将奇数取出来,偶数取出来,然后贪心取头即可。

    代码:

    view code
    #pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define endl "
    " 
    using namespace std;
    using db = double;
    using ll = long long;
    using ull = unsigned long long; 
    using pII = pair <int, int>;
    using pLL = pair <ll, ll>;
    constexpr int mod = 1e9 + 7;
    template <class T1, class T2> inline void chadd(T1 &x, T2 y) { x += y; while (x >= mod) x -= mod; while (x < 0) x += mod; } 
    template <class T1, class T2> inline void chmax(T1 &x, T2 y) { if (x < y) x = y; }
    template <class T1, class T2> inline void chmin(T1 &x, T2 y) { if (x > y) x = y; }
    inline int rd() { int x; cin >> x; return x; }
    template <class T> inline void rd(T &x) { cin >> x; }
    template <class T> inline void rd(vector <T> &vec) { for (auto &it : vec) cin >> it; }  
    #define dbg(x...) do { cout << "33[32;1m" << #x << " -> "; err(x); } while (0) 
    void err() { cout << "33[39;0m" << endl; } 
    template <class T, class... Ts> void err(const T& arg, const Ts&... args) { cout << arg << ' '; err(args...); }
    template <template<typename...> class T, typename t, typename... A> 
    void err(const T <t> &arg, const A&... args) { for (auto &v : arg) cout << v << ' '; err(args...); }
    inline void pt() { cout << endl; } 
    template <class T, class... Ts> void pt(const T& arg, const Ts&... args) { cout << arg << ' '; pt(args...); }
    template <template<typename...> class T, typename t, typename... A> 
    void pt(const T <t> &arg, const A&... args) { for (auto &v : arg) cout << v << ' '; pt(args...); }
    ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
    inline ll qpow(ll base, ll n) { ll res = 1; while (n) { if (n & 1) res = res * base % mod; base = base * base % mod; n >>= 1; } return res; }
    //head
    constexpr int N = 3e5 + 10;
    int n; char s[N]; 
    void out(vector <int> &vec) {
    	cout << vec.back();
    	vec.pop_back();
    }
    void run() {
    	vector <int> vec[2];
    	cin >> (s + 1);
    	for (int i = 1; s[i]; ++i) {
    		int num = s[i] - '0';
    		vec[num & 1].push_back(num);
    	}
    	reverse(vec[0].begin(), vec[0].end());
    	reverse(vec[1].begin(), vec[1].end());
    	while (!vec[0].empty() || !vec[1].empty()) {
    		if (vec[0].empty()) {
    			out(vec[1]);
    		} else if (vec[1].empty()) {
    			out(vec[0]);
    		} else {
    			if (vec[0].back() < vec[1].back()) {
    				out(vec[0]);
    			} else {
    				out(vec[1]);
    			}
    		}
    	}
    	cout << endl;
    }
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(nullptr); cout.tie(nullptr);
    	cout << fixed << setprecision(20);
    	int _T; cin >> _T;
    	while (_T--) run();
    	return 0;
    }
    

    D. Salary Changing

    题意:
    (n)个人,你是老板,你手里有(s)元钱,要给这(n)个人发工资,每个人工资的范围是([l_i, r_i]),要如何发工资使得你的钱够用并且(n)个人工资的中位数最高。

    思路:
    首先给每个人发(l_i)工资,那么得到一个答案的下界,那么发现这个下界到(INF)这个范围,答案具有单调性,二分然后贪心(check)即可。

    代码:

    view code
    #pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define endl "
    " 
    using namespace std;
    using db = double;
    using ll = long long;
    using ull = unsigned long long; 
    using pII = pair <int, int>;
    using pLL = pair <ll, ll>;
    constexpr int mod = 1e9 + 7;
    template <class T1, class T2> inline void chadd(T1 &x, T2 y) { x += y; while (x >= mod) x -= mod; while (x < 0) x += mod; } 
    template <class T1, class T2> inline void chmax(T1 &x, T2 y) { if (x < y) x = y; }
    template <class T1, class T2> inline void chmin(T1 &x, T2 y) { if (x > y) x = y; }
    inline int rd() { int x; cin >> x; return x; }
    template <class T> inline void rd(T &x) { cin >> x; }
    template <class T> inline void rd(vector <T> &vec) { for (auto &it : vec) cin >> it; }  
    #define dbg(x...) do { cout << "33[32;1m" << #x << " -> "; err(x); } while (0) 
    void err() { cout << "33[39;0m" << endl; } 
    template <class T, class... Ts> void err(const T& arg, const Ts&... args) { cout << arg << ' '; err(args...); }
    template <template<typename...> class T, typename t, typename... A> 
    void err(const T <t> &arg, const A&... args) { for (auto &v : arg) cout << v << ' '; err(args...); }
    inline void pt() { cout << endl; } 
    template <class T, class... Ts> void pt(const T& arg, const Ts&... args) { cout << arg << ' '; pt(args...); }
    template <template<typename...> class T, typename t, typename... A> 
    void pt(const T <t> &arg, const A&... args) { for (auto &v : arg) cout << v << ' '; pt(args...); }
    ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
    inline ll qpow(ll base, ll n) { ll res = 1; while (n) { if (n & 1) res = res * base % mod; base = base * base % mod; n >>= 1; } return res; }
    //head
    constexpr int N = 2e5 + 10;
    int n; ll s;
    pII a[N];
    bool check(ll x) {
    	int l = 0, r = 0;
    	ll remind = s;
    	for (int i = 1; i <= n; ++i) {
    		if (a[i].se < x) {
    			remind -= a[i].fi;
    			++l;
    		} else if (a[i].fi > x) {
    			remind -= a[i].fi;
    			++r;
    		} 
    	}
    	if (l > n / 2 || r > n / 2) return false;
    	for (int i = 1; i <= n; ++i) {
    		if (a[i].fi <= x && a[i].se >= x) {
    			if (l < n / 2) {
    				++l;
    				remind -= a[i].fi;
    			} else {
    				remind -= x;
    			}
    		}
    	}
    	return remind >= 0;
    }
    void run() {
    	cin >> n >> s;
    	for (int i = 1; i <= n; ++i) a[i].fi = rd(), a[i].se = rd();
    	sort(a + 1, a + 1 + n);
    	ll l = a[n / 2 + 1].fi, r = 1e9, res = l;
    	while (r - l >= 0) {
    		ll mid = (l + r) >> 1;
    		if (check(mid)) {
    			res = mid;
    			l = mid + 1;
    		} else {
    			r = mid - 1;
    		}
    	}
    	pt(res);
    }
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(nullptr); cout.tie(nullptr);
    	cout << fixed << setprecision(20);
    	int _T = rd();
    	while (_T--) run();
    	return 0;
    }
    

    E2. Voting (Hard Version)

    题意:
    (n)个人,你可以花费(p_i)让第(i)个人投票,或者拉够(m_i)个人为你投票,这个人就会为你投票。
    现在你想让所有人都为你投票,需要花费的最小代价是多少?

    思路:
    假设我知道有(x)个人不需要花费代价能让他们为我免费投票,那么我假设刚开始对每个人都付了钱让他们投票,现在就是要去除(x)个人的花费,使得去除的花费最大。
    那么我们从(i in [x, n])扫一遍,用一个大根堆维护(m_i < i)的所有人的最大(p_i),每次取出堆顶的(p_i)即可。
    并且容易发现(x)具有单调性,直接二分即可。

    代码:

    view code
    #pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define endl "
    " 
    using namespace std;
    using db = double;
    using ll = long long;
    using ull = unsigned long long; 
    using pII = pair <int, int>;
    using pLL = pair <ll, ll>;
    constexpr int mod = 1e9 + 7;
    template <class T1, class T2> inline void chadd(T1 &x, T2 y) { x += y; while (x >= mod) x -= mod; while (x < 0) x += mod; } 
    template <class T1, class T2> inline void chmax(T1 &x, T2 y) { if (x < y) x = y; }
    template <class T1, class T2> inline void chmin(T1 &x, T2 y) { if (x > y) x = y; }
    inline int rd() { int x; cin >> x; return x; }
    template <class T> inline void rd(T &x) { cin >> x; }
    template <class T> inline void rd(vector <T> &vec) { for (auto &it : vec) cin >> it; }  
    #define dbg(x...) do { cout << "33[32;1m" << #x << " -> "; err(x); } while (0) 
    void err() { cout << "33[39;0m" << endl; } 
    template <class T, class... Ts> void err(const T& arg, const Ts&... args) { cout << arg << ' '; err(args...); }
    template <template<typename...> class T, typename t, typename... A> 
    void err(const T <t> &arg, const A&... args) { for (auto &v : arg) cout << v << ' '; err(args...); }
    inline void pt() { cout << endl; } 
    template <class T, class... Ts> void pt(const T& arg, const Ts&... args) { cout << arg << ' '; pt(args...); }
    template <template<typename...> class T, typename t, typename... A> 
    void pt(const T <t> &arg, const A&... args) { for (auto &v : arg) cout << v << ' '; pt(args...); }
    ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
    inline ll qpow(ll base, ll n) { ll res = 1; while (n) { if (n & 1) res = res * base % mod; base = base * base % mod; n >>= 1; } return res; }
    //head
    constexpr int N = 2e5 + 10;
    int n; vector <vector<int>> vec;
    ll gao(int x) {
    	ll tot = 0;
    	priority_queue <int, vector<int>, less<int>> pq;
    	for (int i = 1; i <= n; ++i) {
    		for (auto &it : vec[i]) pq.push(it);
    		if (i >= x) {
    			if (pq.empty()) return 0;
    			tot += pq.top(); pq.pop();
    		}
    	}
    	return tot;
    }
    void run() {
    	n = rd();
    	vec.clear(); vec.resize(n + 1);
    	ll tot = 0;
    	for (int i = 1, m, p; i <= n; ++i) {
    		m = rd(); p = rd();
    		vec[m + 1].push_back(p);
    		tot += p;
    	}
    	int l = 1, r = n; ll Max = 0;
    	while (r - l >= 0) {
    		int mid = (l + r) >> 1;
    		ll tmp = gao(mid);
    		chmax(Max, tmp);
    		//dbg(l, r, mid, Max);
    		if (tmp > 0) {
    			r = mid - 1;
    		} else {
    			l = mid + 1;
    		}
    	}
    	pt(tot - Max);
    }
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(nullptr); cout.tie(nullptr);
    	cout << fixed << setprecision(20);
    	int _T = rd();
    	while (_T--) run();
    	return 0;
    }
    
  • 相关阅读:
    【CF741D】Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)
    【CF600E】Lomsat gelral(dsu on tree)
    【Vijos】lxhgww的奇思妙想(长链剖分)
    【HDOJ6586】String(枚举)
    【HDOJ6578】Blank(DP)
    【HDOJ6583】Typewriter(SAM,DP)
    JAVA 集合 List 分组的两种方法
    HashMap的实现原理
    HashMap, HashTable, CurrentHashMap的区别
    java ThreadLocal(应用场景及使用方式及原理)
  • 原文地址:https://www.cnblogs.com/Dup4/p/11736048.html
Copyright © 2020-2023  润新知