MMOI R1 T1-3 题解
2026-06-14 22:42:55
发布于:广东
难度大概是橙橙黄绿吧。感谢金钩大佬在百忙之中出神题 / 神人题给我们。
T1
Difficulty:3- / Easy
Tag:-
假设存在一个 使得满足 的数量大于 。
注意到是排列,所以不可能。
所以修改显然不优。
所以最优解是不把任何平台修改接收平台,答案就是 的数量。
namespace cjdst{
void solve(){
int n, m;
std::cin >> n >> m;
int ans = 0;
std::vector <int> a(n + 5);
for(int i = 1; i <= n; i++){
std::cin >> a[i];
ans += (a[i] <= i);
}
std::cout << ans << '\n';
while(m--){
int x, y;
std::cin >> x >> y;
ans -= (a[x] <= x) + (a[y] <= y);
std::swap(a[x], a[y]);
ans += (a[x] <= x) + (a[y] <= y);
std::cout << ans << '\n';
}
}
}
时间复杂度:。
T2
Difficulty:3.4 / Easy
Tag:-
脑电波题。
注意到如果 是奇数,出现的数只有奇数和 可以这么构造:
偶数同理。
然后注意到把这两块拼出来,中间有三个 ,而最左边和最右边的空的距离恰好是 ,刚好能放进 。所以构造如下(这里展示 的):
namespace cjdst{
void solve(){
int n;
std::cin >> n;
for(int i = (n - 1) / 2 * 2 - n % 2 * 2 + 1; i >= 1; i -= 2){
std::cout << i << ' ';
}
std::cout << n << ' ';
for(int i = 1; i <= (n - 1) / 2 * 2 - n % 2 * 2 + 1; i += 2){
std::cout << i << ' ';
}
for(int i = (n - 1) / 2 * 2; i >= 2; i -= 2){
std::cout << i << ' ';
}
std::cout << "0 " << n << ' ';
for(int i = 2; i <= (n - 1) / 2 * 2; i += 2){
std::cout << i << ' ';
}
std::cout << '\n';
}
}
时间复杂度:。
T3
Difficulty:3.5 / Easy
Tag:隔板法
首先计算长度为 的方程数。
其实就是求 , 的整数解数量。容斥一下,分别计算 与 的非负整数解数量。这里讨论前者。
移一下项,。根据隔板法,答案为 。
所以总数为 。第二问就是在问满足 的最小的 。
注意到 增长极快,当 较大时, 时原式就已经超过 了。所以组合数怎么实现都行。
我使用了一种十分拟人的 实现求组合数。能过就是好算法
namespace cjdst{
const ll mod = 998244353;
ll C(ll n, ll m){
if(n <= 0 || m < 0) return 0;
if(m == 0) return 1;
std::map <ll, ll> mp;
for(ll i = n - m + 1; i <= n; i++){
ll cur = i;
for(ll j = 2; j * j <= cur; j++){
while(cur % j == 0){
mp[j]++;
cur /= j;
}
}
if(cur != 1) mp[cur]++;
}
for(ll i = 1; i <= m; i++){
ll cur = i;
for(ll j = 2; j * j <= cur; j++){
while(cur % j == 0){
mp[j]--;
cur /= j;
}
}
if(cur != 1) mp[cur]--;
}
ll ans = 1;
for(auto it:mp){
for(int j = 1; j <= it.second; j++){
ans *= it.first;
if(ans > int(1e9)) return 0x3f3f3f3f;
}
}
return ans;
}
void solve(){
int n, m;
std::cin >> n >> m;
ll ans = 1, x = 2, y = n - 1;
while(y){
if(y & 1) ans = ans * x % mod;
x = x * x % mod, y >>= 1;
}
ll ans2 = 0, cur = 0;
while(cur + C(n, ans2) - C(n - 1, ans2 - 1) < m){
cur += C(n, ans2) - C(n - 1, ans2 - 1);
ans2++;
}
std::cout << ans << ' ' << ans2 << '\n';
}
}
时间复杂度:。
T4
不会。
全部评论 2
4
1小时前 来自 浙江
0d
19小时前 来自 广东
0
























有帮助,赞一个