【学习笔记】AGC054C Roughly Sorted

已经缺乏深邃的思考力了

c i c_i ci表示 i i i之前比 p i p_i pi大的数的个数。合法的 P P P的步数下界是 ∑ i = 1 n max ⁡ ( c i − K , 0 ) \sum_{i=1}^n\max(c_i-K,0) i=1nmax(ciK,0)。并且可以注意到, { { c i } ∣ c i < i } \{\{c_i\}|c_i<i\} {{ci}ci<i}与序列 P P P形成双射关系。

显然下界是能取到的。如果取不到就没办法做 难点在于观察到。发现 d ( P , P ′ ) d(P,P') d(P,P)不好刻画,但是我们能得到形式化的构造过程:从左往右考虑,如果 c i ′ > K c_i'>K ci>K那么就把 i i i向前移 c i − K c_i-K ciK个位置。结合题意,我们得到 P P P c i < K c_i<K ci<K的点没有移动,那么我们只需求出 P P P c i = K c_i=K ci=K的点能向后移动的距离然后乘起来即可。事实上因为后面的数都比 p i p_i pi大所以答案是 ∏ c i = K ( n − i + 1 ) \prod_{c_i=K}(n-i+1) ci=K(ni+1)。复杂度 O ( n ) O(n) O(n)

#include<bits/stdc++.h> #define pb push_back #define ll long long #define inf 0x3f3f3f3f using namespace std; const int mod=998244353; int n,K,p[5005]; ll mul=1; int main(){ ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); cin>>n>>K;for(int i=1;i<=n;i++)cin>>p[i]; for(int i=1;i<=n;i++){ int l=0;for(int j=1;j<i;j++)if(p[j]>p[i])l++; if(l>K){ cout<<0; return 0; } if(l==K){ int r=1; for(int j=i+1;j<=n;j++){ if(p[j]>p[i])r++; else break; }mul=mul*r%mod; } }cout<<mul; }

__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17530063.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(10)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示