CodeTON Round 9 题解(A~E)
A. Shohag Loves Mod
直接构造
#include <bits/stdc++.h>
void solve()
{
int n; std::cin >> n;
for(int i = 0; i < n; i++) std::cout << 2 * i + 1 << " \n"[i == n - 1];
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t; std::cin >> t;
while(t--) solve();
return 0;
}
B. Shohag Loves Strings
观察一下发现连续两个相同的字符或者连续三个不同的字符是合法的,直接枚举判断
#include <bits/stdc++.h>
void solve()
{
std::string s; std::cin >> s;
int n = s.size();
for(int i = 0; i + 1 < n; i++)
{
if(s[i] == s[i + 1])
{
std::cout << s[i] << s[i] << "\n";
return;
}
}
for(int i = 0; i + 2 < n; i++)
{
if(s[i] != s[i + 2])
{
std::cout << s[i] << s[i + 1] << s[i + 2] << "\n";
return;
}
}
std::cout << -1 << "\n";
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t; std::cin >> t;
while(t--) solve();
return 0;
}
C1. Shohag Loves XOR (Easy Version)
要满足
#include <bits/stdc++.h>
using i64 = long long;
void solve()
{
int x; std::cin >> x;
i64 m; std::cin >> m;
int log = std::__lg(x) + 1;
int N = 1 << log;
int ans = 0;
for(int i = 1; i < N && i <= m; i++)
{
int t = x ^ i;
if(t == 0) continue;
if(x % t == 0 || i % t == 0) ans++;
}
std::cout << ans << "\n";
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t; std::cin >> t;
while(t--) solve();
return 0;
}
后来发现好像有个结论
C2. Shohag Loves XOR (Hard Version)
小范围跟上题做法一样,同时我们也能观察到大范围的时候
#include <bits/stdc++.h>
using i64 = long long;
void solve()
{
int x; std::cin >> x;
i64 m; std::cin >> m;
int log = std::__lg(x) + 1;
int N = 1 << log;
i64 ans = 0;
for(int i = 1; i < N && i <= m; i++)
{
int t = x ^ i;
if(t % x == 0 || t % i == 0) ans++;
}
i64 max = m / x;
if(m >= N - 1)
{
ans += max;
for(int i = 1; 1LL * i * x < N; i++) // 已经在上面算过了
{
i64 t = i * x ^ x;
ans--;
}
for(i64 i = max, j = 100; i * x >= N && j; j--, i--) // 删掉一些不合法的
{
i64 t = i * x ^ x;
if(t > m) ans--;
}
for(i64 i = max + 1, j = 0; i * x >= N && j < 100; j++, i++) // 加上一些可能漏判的
{
i64 t = i * x ^ x;
if(t <= m) ans++;
}
}
std::cout << ans << "\n";
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t; std::cin >> t;
while(t--) solve();
return 0;
}
D. Shohag Loves GCD
要求字典序最大,所以我们优先填大的数,同时如果
#include <bits/stdc++.h>
using i64 = long long;
void solve()
{
int n, m; std::cin >> n >> m;
std::vector<int> s(m);
for(int i = 0; i < m; i++) std::cin >> s[i];
std::ranges::sort(s, std::greater());
std::vector<int> a(n);
for(int i = 1; i <= n; i++)
for(int j = 2 * i; j <= n; j += i)
if(a[j - 1] == a[i - 1])
a[j - 1]++;
if(*max_element(a.begin(), a.end()) >= m)
{
std::cout << -1 << "\n";
return;
}
for(int i = 0; i < n; i++) std::cout << s[a[i]] << " \n"[i == n - 1];
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t; std::cin >> t;
while(t--) solve();
return 0;
}
E. Shohag Loves Inversions
首先我们可以注意到,逆序对的数量是单调不减的,这就意味着,一个数组只有一种产生方式,因为大的数一定是在小的数出现之后再出现的(这里我们把连续相同的数字的产生方式全部定义为加入到这些数的末尾),所以我们在计数的过程中不需要考虑重复的问题。
同时我们可以发现,由于初始的数组只包含
这是因为,对于一个长度为
现在让我们考虑初始情况,可以发现形如
最后的答案为
因为每个长度的数组都可以一直往后加数,同时加上逆序数小于等于
#include <bits/stdc++.h>
using i64 = long long;
constexpr int P = 998244353;
constexpr int N = 1e6;
i64 f[N + 1];
void solve()
{
int n; std::cin >> n;
std::cout << (f[n] + n - 1) % P << "\n";
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
for(int i = 3; i <= N; i++) f[i] = (1LL * (i - 2) * (i - 1) / 2 - 1) % P;
i64 sum = 0;
for(int i = 1; i <= N; i++)
{
f[i] = (f[i] + sum) % P;
sum = (sum + i * f[i] % P) % P;
f[i] = (f[i] + f[i - 1]) % P;
}
int t; std::cin >> t;
while(t--) solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!