AtCoder Grand Contest 054 C Roughly Sorted

考虑一个合法的 P,记 ai=j=1i1[Pj>Pi],则通过简单推理可得 ai<ai+1Pi>Pi+1。易知一次合法交换操作 (i,i+1) 当且仅当 ai<ai+1ai+1>K,否则就不能使得交换次数最小,并且交换后 aiai1

现在已知 P,考虑求 bi=j=1i1[Pj>Pi],并且进行逆操作。因此一次交换操作 (i,i+1) 合法当且仅当 bibi+1biK,且交换后 bi+1bi+1+1。逆序考虑所有满足 bi=Ki,则 Pi 最多可以往右移 ni 次,有 ni+1 种选择。根据乘法原理易得答案为 bi=K(ni+1)

时间复杂度 O(n2),若使用树状数组求 b 则复杂度降为 O(nlogn)

code
// Problem: C - Roughly Sorted
// Contest: AtCoder - AtCoder Grand Contest 054
// URL: https://atcoder.jp/contests/agc054/tasks/agc054_c
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mems(a, x) memset((a), (x), sizeof(a))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;
const int maxn = 5050;
const ll mod = 998244353;
int n, m, a[maxn], b[maxn];
void solve() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j < i; ++j) {
b[i] += (a[j] > a[i]);
}
}
ll ans = 1;
for (int i = 1; i <= n; ++i) {
if (b[i] == m) {
ans = ans * (n - i + 1) % mod;
}
}
printf("%lld\n", ans);
}
int main() {
int T = 1;
// scanf("%d", &T);
while (T--) {
solve();
}
return 0;
}
posted @   zltzlt  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示