Codeforces Global Round 26
A
如果 \(a_1 = a_n\),無解。
如果 \(a_2 = a_n\),\(a_1, a_2\) 塗成紅色,否則只把 \(a_1\) 塗成紅色。
void solve() {
cin >> n;
for(int i = 1; i <= n; ++ i) cin >> a[i];
if(a[1] == a[n]) {
cout << "NO\n";
return;
}
cout << "YES\n";
if(a[2] != a[n]) {
cout << "R";
for(int i = 2; i <= n; ++ i) {
cout << "B";
}
cout << '\n';
return;
}
cout << "RR";
for(int i = 3; i <= n; ++ i) {
cout << "B";
}
cout << '\n';
}
B
如果首位不等於 \(1\),無解。
否則可以推出兩個數 \(a + b = x\) 每一位的和,且這個和一定屬於 \([10, 18]\),否則無解。
例如:\(1393938\)。
- \(a_0 + b_0 = 18\)。
- \(a_1 + b_1 = 13 - 1\)(一定有進位)。
- \(a_2 + b_2 = 19 - 1\)。
以此類推。
void solve() {
ll x; cin >> x;
auto s = to_string(x);
int n = s.length();
if(s[0] != '1') {
cout << "NO\n";
return;
}
for(int i = 0; i <= n - 2; ++ i) {
int x = 10 + s[i + 1] - '0';
if(i != n - 2) -- x;
if(x < 10 || x > 18) {
cout << "NO\n";
return;
}
}
cout << "YES\n";
}
C1
void solve() {
ll n, mi = 0, mx = 0;
cin >> n;
for(int i = 1; i <= n; ++ i) {
int x; cin >> x;
ll pi = mi, px = mx;
mx = max({px + x, abs(px + x), pi + x, abs(pi + x)});
mi = min({px + x, abs(px + x), pi + x, abs(pi + x)});
}
cout << mx << '\n';
}
C2
void solve() {
ll n, mi = 0, mx = 0, ai = 1, ax = 1;
cin >> n;
for(int i = 1; i <= n; ++ i) {
int x; cin >> x;
ll pi = mi, px = mx;
ll pai = ai, pax = ax;
mx = max({px + x, abs(px + x), pi + x, abs(pi + x)});
mi = min({px + x, abs(px + x), pi + x, abs(pi + x)});
ai = 0;
ax = 0;
ax = (ax + pax * ( (mx == px + x) + (mx == (abs(px + x)) ) ) ) % P;
ai = (ai + pax * ( (mi == px + x) + (mi == (abs(px + x)) ) ) ) % P;
if(px != pi) {
ax = (ax + pai * ( (mx == pi + x) + (mx == (abs(pi + x)) ) ) ) % P;
ai = (ai + pai * ( (mi == pi + x) + (mi == (abs(pi + x)) ) ) ) % P;
}
}
cout << ax << '\n';
}
D
設 \(s\) 長度為 \(n\)。特判全為 a
的情況,共 \(n - 1\) 種方案。
設 \(s\) 中非 a
字元的數量為 \(m\)。
如果 \(t\) 中有 \(k\) 個非 a
字元,把 \(t\) 掐頭去尾忽略前後的 a
後,原串裡一定恰好存在 \(\dfrac{m}{k}\) 個 \(t'\),且 \(k\mid m\)。
列舉 \(k\)。記錄第 \(i\) 個非 a
字元的位置為 \(p_i\)(從 \(0\) 開始),如果 \(s_{p_i} \ne s_{p_i - k}\) 或不在分割處的 \(p_i - p_{i - 1}\ne p_{i - k} - p_{i - k - 1}\),\(t'\) 不合法。
把 \(t'\) 還原為 \(t\),列舉左邊有的 a
個數 \(l \in [0, p_0]\)。
設 \(x\) 為分割處的最小間隔 \(\min(p_i - p_{i - 1}),\ k \mid i\),則右邊的 a
個數 \(r \in [0, \min(x - l, n - p_{m - 1} - 1)]\)。
void solve() {
string s;
cin >> s;
int n = s.length();
if(count(s.begin(), s.end(), 'a') == n) {
cout << n - 1 << '\n';
return;
}
vector<int> a;
for(int i = 0; i < n; ++ i) {
if(s[i] != 'a') {
a.eb(i);
}
}
int m = a.size();
ll ans = 0;
for(int i = 1; i <= m; ++ i) {
if(m % i) {
continue;
}
int ok = 1;
for(int j = i; j < m; ++ j) {
int o = j % i;
if(s[a[j]] != s[a[o]] || (o && a[o] - a[o - 1] != a[j] - a[j - 1])) {
ok = 0;
break;
}
}
if(ok) {
int mi = n;
for(int j = i; j < m; j += i) {
mi = min(mi, a[j] - a[j - 1] - 1);
}
int r = n - a.back() - 1;
for(int l = 0; l <= a[0]; ++ l) {
ans += max(0, min(r + 1, mi - l + 1));
}
}
}
cout << ans << '\n';
}