说实话这绝对是我做过最垃圾的一套 ARC 了,没有之一。
D – Worst Case
这个题有点像我之前 Codeforces 做过的一个题,但是好像不是一样的,所以被卡了好久。
首先考虑几个特判,我们先设 \(A < B\):
- \(A = B\),这个答案就是 \(2(A – 1)\),没什么好说的。
- \(A = B – 1\),这个的话答案也是 \(2(A – 1)\),没什么好说的。
之后考虑 \(A < B – 1\) 的情况了。首先他们的这个积最后是 \(A\times B\)。我们要数清楚有多少个 \((x, y), x \times y < A \times B\)。其实想到这里可以尝试找一个 \(C\) 使得 \(C^2 < AB\)。这个时候一般会存在 \(A < C < B\) 的情况。如果 \(C(C + 1) < AB\) 那么答案为 \(2C – 1\),否则为 \(2C – 2\)。
发现其实 \(C(C + 1)\) 其实是一组解,所以我们先来思考为什么答案是 \(2C – 2\)。可以考虑构造 \((1, A + B – 1), (2, A + B), \dots, (A – 1, B + 1), (A + 1, 2C – A – 1), \dots, (C, C), \dots (2C, 1)\)。
scanf("%lld%lld", &a, &b);
if (a == b || a + 1 == b)
ll C = sqrt(1LL * a * b) - 1;
while ((C + 1) * (C + 1) < 1LL * a * b)
if (C * (C + 1) >= 1LL * a * b)
// ARC094B.cpp
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll Q, n = 1e12, a, b;
int main()
{
scanf("%lld", &Q);
while (Q--)
{
scanf("%lld%lld", &a, &b);
if (a > b)
swap(a, b);
ll ans = 0;
if (a == b || a + 1 == b)
ans += 2LL * a - 2;
else
{
ll C = sqrt(1LL * a * b) - 1;
while ((C + 1) * (C + 1) < 1LL * a * b)
C++;
if (C * (C + 1) >= 1LL * a * b)
ans = 2LL * C - 2;
else
ans = 2LL * C - 1;
}
printf("%lld\n", ans);
}
return 0;
}
// ARC094B.cpp
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll Q, n = 1e12, a, b;
int main()
{
scanf("%lld", &Q);
while (Q--)
{
scanf("%lld%lld", &a, &b);
if (a > b)
swap(a, b);
ll ans = 0;
if (a == b || a + 1 == b)
ans += 2LL * a - 2;
else
{
ll C = sqrt(1LL * a * b) - 1;
while ((C + 1) * (C + 1) < 1LL * a * b)
C++;
if (C * (C + 1) >= 1LL * a * b)
ans = 2LL * C - 2;
else
ans = 2LL * C - 1;
}
printf("%lld\n", ans);
}
return 0;
}
E – Tozan and Gezan
Tozan 可以直接随心所欲的走,而 Gezan 并不能进行有效的抑制。最后情况一定会是 \(0, 0, 0, 0, \dots, b_i, 0, \dots\)。所以最后 Candy 计数肯定会把所有的 \(a_i\) 计入,但是除了中间的 \(b_i\)。这个 \(b_i\) 取 \(a_i > b_i\) 时的最小值,因为只有这个情况会出现在最后状态下。
const int MAX_N = 2e5 + 200;
typedef pair<int, int> pii;
int n, ai[MAX_N], bi[MAX_N];
long long ans = 0, acc = 1LL << 30;
for (int i = 1; i <= n; i++)
scanf("%d%d", &ai[i], &bi[i]);
flag &= (ai[i] == bi[i]), ans += ai[i];
acc = min(acc, 1LL * bi[i]);
printf("%lld\n", ans - acc);
// ARC094C.cpp
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 2e5 + 200;
typedef pair<int, int> pii;
int n, ai[MAX_N], bi[MAX_N];
priority_queue<pii> pq1;
multiset<pii> pq2;
int main()
{
scanf("%d", &n);
long long ans = 0, acc = 1LL << 30;
bool flag = true;
for (int i = 1; i <= n; i++)
{
scanf("%d%d", &ai[i], &bi[i]);
flag &= (ai[i] == bi[i]), ans += ai[i];
if (ai[i] > bi[i])
acc = min(acc, 1LL * bi[i]);
}
if (flag)
puts("0");
else
printf("%lld\n", ans - acc);
return 0;
}
// ARC094C.cpp
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 2e5 + 200;
typedef pair<int, int> pii;
int n, ai[MAX_N], bi[MAX_N];
priority_queue<pii> pq1;
multiset<pii> pq2;
int main()
{
scanf("%d", &n);
long long ans = 0, acc = 1LL << 30;
bool flag = true;
for (int i = 1; i <= n; i++)
{
scanf("%d%d", &ai[i], &bi[i]);
flag &= (ai[i] == bi[i]), ans += ai[i];
if (ai[i] > bi[i])
acc = min(acc, 1LL * bi[i]);
}
if (flag)
puts("0");
else
printf("%lld\n", ans - acc);
return 0;
}
F – Normalization
就是这个题让整套题都很烂了(
想半天去看个题解,最后发现是个结论题,而且没有任何证明(四色定理式证明),我是佛了。
const int MAX_N = 2e5 + 200, mod = 998244353;
int n, dp[MAX_N][3][3][2], str[MAX_N];
scanf("%s", org + 1), n = strlen(org + 1);
int oddity = 0, tot[3] = {0, 0, 0};
for (int i = 1; i <= n; i++)
str[i] = org[i] - 'a', oddity = (oddity + str[i]) % 3, tot[str[i]]++;
for (int i = 1; i < n; i++)
flag &= (str[i] != str[i + 1]);
if (tot[0] == n || tot[1] == n || tot[2] == n)
string org_str = org + 1;
for (int i = 0; i < n - 1; i++)
if (x.first[i] != x.first[i + 1])
nxt[i] = nxt[i + 1] = ('a' ^ 'b' ^ 'c') ^ (x.first[i] ^ x.first[i + 1]);
printf("%lld\n", 1LL * mp.size());
int ans = (flag == true);
dp[1][0][0][0] = dp[1][1][1][0] = dp[1][2][2][0] = 1;
for (int i = 2; i <= n; i++)
for (int sum = 0; sum < 3; sum++)
for (int pre = 0; pre < 3; pre++)
for (int curt = 0; curt < 3; curt++)
dp[i][(sum + curt) % 3][curt][1] = (0LL + dp[i][(sum + curt) % 3][curt][1] + dp[i - 1][sum][pre][0] + dp[i - 1][sum][pre][1]) % mod;
dp[i][(sum + curt) % 3][curt][0] = (0LL + dp[i][(sum + curt) % 3][curt][0] + dp[i - 1][sum][pre][0]) % mod;
dp[i][(sum + curt) % 3][curt][1] = (0LL + dp[i][(sum + curt) % 3][curt][1] + dp[i - 1][sum][pre][1]) % mod;
for (int i = 0; i < 3; i++)
ans = (0LL + ans + dp[n][oddity][i][1]) % mod;
// ARC094D.cpp
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 2e5 + 200, mod = 998244353;
int n, dp[MAX_N][3][3][2], str[MAX_N];
char org[MAX_N];
int main()
{
scanf("%s", org + 1), n = strlen(org + 1);
int oddity = 0, tot[3] = {0, 0, 0};
bool flag = true;
for (int i = 1; i <= n; i++)
str[i] = org[i] - 'a', oddity = (oddity + str[i]) % 3, tot[str[i]]++;
for (int i = 1; i < n; i++)
flag &= (str[i] != str[i + 1]);
if (tot[0] == n || tot[1] == n || tot[2] == n)
puts("1"), exit(0);
if (n <= 3)
{
map<string, bool> mp;
string org_str = org + 1;
mp[org_str] = true;
int delta = 0;
do
{
delta = 0;
for (auto x : mp)
for (int i = 0; i < n - 1; i++)
if (x.first[i] != x.first[i + 1])
{
string nxt = x.first;
nxt[i] = nxt[i + 1] = ('a' ^ 'b' ^ 'c') ^ (x.first[i] ^ x.first[i + 1]);
if (mp[nxt] == false)
mp[nxt] = true, delta++;
}
} while (delta);
printf("%lld\n", 1LL * mp.size());
}
else
{
int ans = (flag == true);
dp[1][0][0][0] = dp[1][1][1][0] = dp[1][2][2][0] = 1;
for (int i = 2; i <= n; i++)
for (int sum = 0; sum < 3; sum++)
for (int pre = 0; pre < 3; pre++)
for (int curt = 0; curt < 3; curt++)
if (pre == curt)
dp[i][(sum + curt) % 3][curt][1] = (0LL + dp[i][(sum + curt) % 3][curt][1] + dp[i - 1][sum][pre][0] + dp[i - 1][sum][pre][1]) % mod;
else
{
dp[i][(sum + curt) % 3][curt][0] = (0LL + dp[i][(sum + curt) % 3][curt][0] + dp[i - 1][sum][pre][0]) % mod;
dp[i][(sum + curt) % 3][curt][1] = (0LL + dp[i][(sum + curt) % 3][curt][1] + dp[i - 1][sum][pre][1]) % mod;
}
for (int i = 0; i < 3; i++)
ans = (0LL + ans + dp[n][oddity][i][1]) % mod;
printf("%d\n", ans);
}
return 0;
}
// ARC094D.cpp
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 2e5 + 200, mod = 998244353;
int n, dp[MAX_N][3][3][2], str[MAX_N];
char org[MAX_N];
int main()
{
scanf("%s", org + 1), n = strlen(org + 1);
int oddity = 0, tot[3] = {0, 0, 0};
bool flag = true;
for (int i = 1; i <= n; i++)
str[i] = org[i] - 'a', oddity = (oddity + str[i]) % 3, tot[str[i]]++;
for (int i = 1; i < n; i++)
flag &= (str[i] != str[i + 1]);
if (tot[0] == n || tot[1] == n || tot[2] == n)
puts("1"), exit(0);
if (n <= 3)
{
map<string, bool> mp;
string org_str = org + 1;
mp[org_str] = true;
int delta = 0;
do
{
delta = 0;
for (auto x : mp)
for (int i = 0; i < n - 1; i++)
if (x.first[i] != x.first[i + 1])
{
string nxt = x.first;
nxt[i] = nxt[i + 1] = ('a' ^ 'b' ^ 'c') ^ (x.first[i] ^ x.first[i + 1]);
if (mp[nxt] == false)
mp[nxt] = true, delta++;
}
} while (delta);
printf("%lld\n", 1LL * mp.size());
}
else
{
int ans = (flag == true);
dp[1][0][0][0] = dp[1][1][1][0] = dp[1][2][2][0] = 1;
for (int i = 2; i <= n; i++)
for (int sum = 0; sum < 3; sum++)
for (int pre = 0; pre < 3; pre++)
for (int curt = 0; curt < 3; curt++)
if (pre == curt)
dp[i][(sum + curt) % 3][curt][1] = (0LL + dp[i][(sum + curt) % 3][curt][1] + dp[i - 1][sum][pre][0] + dp[i - 1][sum][pre][1]) % mod;
else
{
dp[i][(sum + curt) % 3][curt][0] = (0LL + dp[i][(sum + curt) % 3][curt][0] + dp[i - 1][sum][pre][0]) % mod;
dp[i][(sum + curt) % 3][curt][1] = (0LL + dp[i][(sum + curt) % 3][curt][1] + dp[i - 1][sum][pre][1]) % mod;
}
for (int i = 0; i < 3; i++)
ans = (0LL + ans + dp[n][oddity][i][1]) % mod;
printf("%d\n", ans);
}
return 0;
}