Educational Codeforces Round 12
Posted zwh_zzz的学习笔记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Educational Codeforces Round 12相关的知识,希望对你有一定的参考价值。
Educational Codeforces Round 12
A Buses Between Cities
做法:把所有的时间都转换成分钟来考虑这个问题,模拟的情况就很简单了,具体看代码。
代码:
void solve()
int a, ta;
int b, tb;
cin >> a >> ta >> b >> tb;
string s;
cin >> s;
int tim = ((s[0] - \'0\') * 10 + (s[1] - \'0\') ) * 60 + ((s[3] - \'0\') * 10 + s[4] - \'0\');
int timend = tim + ta;
int ans = 0;
for (int now = 300;now < 24 * 60;)
if(now <= tim && (now + tb) > tim)
ans ++;
else if(now > tim && now < timend)
ans++;
now += b;
cout << ans << endl;
B Shopping
做法:直接看样例模拟,具体的意思就是每次排列会交换位置,输出数的位置权值和,鉴定为样例比题目好看懂。
代码:
void solve()
int n , m , k;
cin >> n >> m >> k;
vector<int> a(k + 1);
vector<int> pos(k + 1);
for (int i = 1;i <= k;i ++) cin >> a[i];
for (int i = 1;i <= k;i ++) pos[a[i]] = i;
int ans = 0;
for (int i = 1;i <= n;i ++)
for (int j = 1;j <= m;j ++)
vector<int> tmp;
tmp.push_back(114514);
int x;
cin >> x;
tmp.push_back(x);
for (int q = 1;q <= k;q ++)
if(a[q] != x)
tmp.push_back(a[q]);
// for (int t : tmp) cout << t << \' \';cout << endl;
for (int i = 1;i <= k;i ++) pos[a[i]] = i;
a = tmp;
ans += pos[x];
cout << ans << endl;
C Simple Strings
做法:氵题,模拟。
代码:
void solve()
string s;
cin >> s;
int n = s.length();
s = " " + s;
for (int i = 1;i <= n;i ++)
if(s[i - 1] == s[i])
if(i + 1 <= n)
for (char op = \'a\';op <= \'z\';op++)
if(op != s[i - 1] && op != s[i + 1]) s[i] = op;
else
for (char op = \'a\';op <= \'z\';op++)
if(op != s[i - 1]) s[i] = op;
for (int i = 1;i <= n;i ++) cout << s[i];cout << endl;
D Simple Subset
做法:需要点神奇思路的题,我们首先考虑这么个情况,假设现在存在三个数,如果其中不含\\(1\\)的话,是不可能满足题目的要求的,我们可以从奇偶性的角度出发,三个数之中,全为奇或偶必寄,剩下的就是有两个为奇,两个为偶这个样子,那么我们就可以发现,因为奇数加奇数为偶数,偶数不可能为素数,所以,三个数寄。
根据样例知道,我们要特判\\(1\\),即可解答。
代码:
int primes[N];
bool st[N];
int cnt;
void init()
for (int i = 2;i < N;i ++)
if(!st[i]) primes[cnt++] = i;
for (int j = 0;j < cnt && primes[j] * i < N;j ++)
st[primes[j] * i] = 1;
if(i % primes[j] == 0) break;
void solve()
int n;
cin >> n;
vector<int> a(n + 1);
int cnt1 = 0;
for (int i = 1;i <= n;i ++)
cin >> a[i];
if(a[i] == 1) cnt1++;
if(cnt1 == 0 || cnt1 == 1)
for (int i = 1;i <= n;i ++)
for (int j = i + 1;j <= n;j ++)
if(!st[a[i] + a[j]])
cout << 2 << endl;
cout << a[i] << \' \' << a[j] << endl;
return ;
cout << 1 << endl;
cout << a[1] << endl;
else
for (int i = 1;i <= n;i ++)
if(!st[a[i] + 1] && a[i] != 1)
cout << cnt1 + 1 << endl;
for (int i = 1;i <= cnt1;i ++) cout << 1 << \' \';
cout << a[i] << endl;
return ;
cout << cnt1 << endl;
while(cnt1--) cout << 1 << \' \';cout << endl;
E Beautiful Subarrays
做法:队友点评为典,对于这个问题我们可以这么考虑,我们如果把题目要求改成异或值等于\\(k\\),那么是不是就很简单了,直接前缀异或和等于k,\\(O(n)\\)的复杂度。但是这里是大于等于\\(k\\),我们考虑建trie树来考虑异或值,从高到低位进行贪心的选择,如果遍历到的这一位为1的话,因为是从高到底考虑的,所以这一位的异或值必须为\\(1\\),对于当前的\\(R_i\\),我们走置反的路,\\(0\\)则\\(1\\),\\(1\\)则\\(0\\)。
如果这一位为\\(0\\),那我们考虑异或为\\(1\\)时肯定最优,所以把异或为1时的子树加入贡献,这里trie的cnt统计为经过每个点的数量,即可做出本题。
代码:
int son[N * 30][2];
int cnt[N * 30];
int idx;
int k;
void insert(int x)
int p = 0;
for (int i = 30;i >= 0;i --)
int &s = son[p][x >> i & 1];
if(!s) s = ++idx;
p = s;
cnt[p]++;
int find(int x)
int p = 0;
int res = 0;
ll ans = 0;
for (int i = 30;i >= 0;i --)
int ck = (k >> i) & 1;
if(ck == 1)
p = son[p][!(x >> i & 1)];
else
ans += cnt[son[p][!(x >> i & 1)]];
p = son[p][(x >> i & 1)];
if(!p) break;
ans += cnt[p];
return ans;
void solve()
int n;
cin >> n >> k;
vector<int> a(n + 1);
for (int i = 1;i <= n;i ++) cin >> a[i];
ll s = 0;
insert(0);
ll ans = 0;
for (int i = 1;i <= n;i ++)
s ^= a[i];
ans += find(s);
insert(s);
cout << ans << endl;
F Four Divisors
做法:这题做法及其简单,难点在于算法。
考虑有四个因子的数,根据因子个数的定理,质因数的次数要么为\\(4\\)要么为两个\\(1\\)。
所以我们需要的是能做到快速的计算\\(\\pi(n)\\),这里套用了别人的Messiel-Lermer的板子,这个算法现在看的还不是很懂,就是黑盒的用了一下。
代码:
namespace pcf
long long dp[MAXN][MAXM];
unsigned int ar[(MAX >> 6) + 5] = 0;
int len = 0, primes[MAXP], counter[MAX];
void Sieve()
setbit(ar, 0), setbit(ar, 1);
for (int i = 3; (i * i) < MAX; i++, i++)
if (!chkbit(ar, i))
int k = i << 1;
for (int j = (i * i); j < MAX; j += k) setbit(ar, j);
for (int i = 1; i < MAX; i++)
counter[i] = counter[i - 1];
if (isprime(i)) primes[len++] = i, counter[i]++;
void init()
Sieve();
for (int n = 0; n < MAXN; n++)
for (int m = 0; m < MAXM; m++)
if (!n) dp[n][m] = m;
else dp[n][m] = dp[n - 1][m] - dp[n - 1][m / primes[n - 1]];
long long phi(long long m, int n)
if (n == 0) return m;
if (primes[n - 1] >= m) return 1;
if (m < MAXM && n < MAXN) return dp[n][m];
return phi(m, n - 1) - phi(m / primes[n - 1], n - 1);
long long Lehmer(long long m)
if (m < MAX) return counter[m];
long long w, res = 0;
int i, a, s, c, x, y;
s = sqrt(0.9 + m), y = c = cbrt(0.9 + m);
a = counter[y], res = phi(m, a) + a - 1;
for (i = a; primes[i] <= s; i++) res = res - Lehmer(m / primes[i]) + Lehmer(primes[i]) - 1;
return res;
void solve()
int n;
pcf::init();
cin >> n;
int ans = 0;
for (int i = 0;i < pcf::len;i ++)
int p = pcf::primes[i];
int y = n / p;
if(p > sqrt(n)) break;
else ans += pcf::Lehmer(y) - pcf::Lehmer(p);
for (int i = 0;i < pcf::len;i++)
int p = pcf::primes[i];
if(p * p * p > n) break;
else ans++;
cout << ans << endl;
以上是关于Educational Codeforces Round 12的主要内容,如果未能解决你的问题,请参考以下文章
Educational Codeforces Round 7 A
Educational Codeforces Round 7
Educational Codeforces Round 90
Educational Codeforces Round 33