zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 86 (Rated for Div. 2) 部分题解

    Educational Codeforces Round 86 (Rated for Div. 2)

    A. Road To Zero

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(nullptr); cout.tie(nullptr);
    	int t; cin >> t;
    	while (t--) {
    		ll x, y, a, b;
    		cin >> x >> y >> a >> b;
    		b = min(a + a, b);
    		cout << min(x, y) * b + (max(x, y) - min(x, y)) * a << "
    ";
    	}
    }
    

    B. Binary Period

    题意:给出一个只由 (0,1) 构成的子串 (t) ,要求你给出一个原串的构造,并且满足原串长度不大于两倍子串长度,同时原串的循环节最短。

    分析:除了全零或者全一的情况,最短的循环节一定是 (01) 或者 (10) ,因此构造一个 (10101010cdots) 的序列,长度为两倍子串长度。这个构造的正确性可以从最极端的反例:子串 (000cdots111) 证明(前一半是 (0),后一半是 (1)),不难发现两倍长度必定够了。

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(nullptr); cout.tie(nullptr);
    	int t; cin >> t;
    	while (t--) {
    		string s; cin >> s;
    		int zero = 0, one = 0;
    		for (auto i : s) {
    			if (i == '1') one++;
    			else zero++;
    		}
    		if (!zero || !one) cout << s << '
    ';
    		else {
    			int n = s.length();
    			while (n--) cout << "10";
    			cout << '
    ';
    		}
    	}
    }
    

    C. Yet Another Counting Problem

    题意:询问 ([l,r]) 中有几个数满足 ((xpmod{a}mod{b}) eq(xpmod{b}mod{a}))

    分析:由于 (a,bleq200) ,因此直接枚举模 (ab) 的同余类(更准确地说,应该枚举 (LCM(a,b))),求一个 ([0,a*b)) 的完全剩余系前缀和,就能 (O(1)) 分段回答询问了。时间复杂度 (O(t(ab+q)))

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    ll a, b, q;
    vector<ll> pre;
    
    ll calc(ll x) {
    	return x / (a * b) * pre[a * b] + pre[x % (a * b)];
    }
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(nullptr); cout.tie(nullptr);
    	int t; cin >> t;
    	while (t--) {
    		cin >> a >> b >> q;
    		pre.resize(a * b + 1, 0);
    		for (int i = 0; i < a * b; ++i)
    			pre[i + 1] = pre[i] + (i % a % b != i % b % a);
    		while (q--) {
    			ll l, r;
    			cin >> l >> r;
    			cout << calc(r + 1) - calc(l) << ' ';
    		}
    		cout << '
    ';
    	}
    }
    

    D. Multiple Testcases

    题意:给定一个大小为 (n) 的数组 (m_n) ,并且该数组中的最大元素不超过 (k) 。要求给出一种构造,将这个数组分配给多个集合,每个集合中的元素必须满足大小 (geq i) 的元素数量不超过 (c_i)

    分析:因为 (c_i) 是一个单调不增的数列,因此本题就是一个从大到小放的贪心,我们优先向一个集合里放入较大的元素。

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(nullptr); cout.tie(nullptr);
    	int n, k;
    	cin >> n >> k;
    	vector<int> cnt(k + 1);
    	vector<int> c(k + 1);
    	for (int i = 0; i < n; ++i) {
    		int x; cin >> x;
    		cnt[x]++;
    	}
    	for (int i = 1; i <= k; ++i) cin >> c[i];
    	vector<vector<int> > res(1);
    	int pre = 0, ans = 0;
    	for (int i = k; i; --i) {
    		int now = 0;
    		if (i != k && c[i] == c[i + 1]) now = pre;
    		while (cnt[i]) {
    			if (now == ans) {
    				++ans;
    				res.emplace_back();
    				continue;
    			}
    			if (res[now].size() < c[i]) {
    				res[now].emplace_back(i);
    				--cnt[i];
    			}
    			else ++now;
    		}
    		pre = now;
    	}
    	cout << ans << '
    ';
    	for (int i = 0; i < ans; ++i) {
    		cout << res[i].size();
    		for (auto j : res[i]) cout << ' ' << j;
    		cout << '
    ';
    	}
    }
    

    E. Placing Rooks

    题意:给定一个 (n imes n) 的棋盘,要求你在棋盘上放 (n) 个车(国际象棋),使得所有格子都能被车在一步内攻击到,询问正好存在 (k) 对车能够相互攻击(不能跨过棋子攻击)的棋子摆法有几种。

    分析:首先,由于所有格子都需要被车在一步内攻击到,因此该棋盘每一行或者每一列都至少有一个车,由此我们能够立刻推出 (F(n,0)=n!) 。并且,由于车不能跨过棋子攻击,因此最多存在 (k-1) 对车能够互相攻击,即 (F(n,k)=0(kgeq n))

    然后,我们考虑存在 (k(n>k>0)) 对车能够相互攻击的情况,不妨假设该棋盘每一行至少有一个车(和每一列至少有一个车的情况是完全对称的,因此结果乘 (2) 即可)。我们将这 (n) 个车看作图上的点,在能够互相攻击的车之间连线,一共需要连 (k) 条线,因此相当于 (n-k) 个连通分量,问题转化为将 (n) 个元素划分为 (n-k) 个子集有几种方法,实际上就是在求第二类斯特林数 (S^{n-k}_n) 。然后,由于每一行都至少有一个车,因此只有 (n-k) 列中有车,相当于在总共 (n) 列的棋盘中选择 (n-k) 列,将答案乘上 (C^{n-k}_{n}) ;并且我们考虑到这 (n-k) 个子集是无序的,因此再乘上 ((n-k)!) 。因此本题的答案为 (2S^{n-k}_nC^{n-k}_n(n-k)!pmod{998244353})

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const ll mod = 998244353;
     
    ll qpow(ll a, ll b, ll mod) {
    	ll ans = 1;
    	while (b) {
    		if (b & 1) ans = (ans * a) % mod;
    		a = (a * a) % mod;
    		b >>= 1;
    	}
    	return ans;
    }
     
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(nullptr); cout.tie(nullptr);
    	ll n, k, ans = 0;
    	cin >> n >> k;
    	if (k >= n) {
    		cout << 0;
    		return 0;
    	}
    	vector<ll> fac(n + 1, 1);
    	for (int i = 2; i <= n; ++i) fac[i] = fac[i - 1] * i % mod;
     
    	auto C = [&](ll n, ll m) {
    		return fac[n] * qpow(fac[m], mod - 2ll, mod) % mod * qpow(fac[n - m], mod - 2ll, mod) % mod;
    	};
     
    	for (int i = 0; i <= n - k; ++i) {
    		ans += ((n - k - i) % 2 == 0 ? 1ll : -1ll) * C(n - k, i) * qpow(i, n, mod) % mod;
    		ans %= mod;
    	}
    	ans = (ans + mod) % mod;
    	ans = (k ? 2ll : 1ll) * ans * C(n, n - k) % mod;
    	cout << ans;
    }
    
  • 相关阅读:
    二开案例.开发环境.从零开发第一个插件和数据字典
    二开案例.开发环境.调试插件代码
    C#中@的用法总结
    金蝶云社区年度资料合辑
    MySQL知识框架[博文汇总-持续更新]
    Redis基础篇(五)AOF与RDB比较和选择策略
    Redis基础篇(四)持久化:内存快照(RDB)
    单调栈技巧总结
    Redis基础篇(三)持久化:AOF日志
    Redis基础篇(二)高性能IO模型
  • 原文地址:https://www.cnblogs.com/st1vdy/p/12784986.html
Copyright © 2011-2022 走看看