思路讲解
的升级版,加了下面这句话
He is allowed to swap two adjacent numbers for no more than k times.
1
| cnt=std::max(cnt-K,0LL);
|
那为什么只要加了这句话就AC了呢?交换两个相邻元素就可以消除逆序对?
首先这个逆序对有两种情况,一种是相邻的逆序对,一种是不相邻的逆序对,比如以下这个
2.....1
中间只能填2,所以任何所谓的超距作用其实中间的所有数必然和那个‘1’是逆序对关系,所以所有逆序对关系都可以转化为相邻逆序对关系。
AC代码
https://vjudge.net/solution/57377152
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| #include <iostream> #include <cstring> #include <algorithm> #include <deque> #include <queue> #include <vector> #include <set> #include <map> #include <cmath> #include <bitset> #include <iterator> #include <random> #include <iomanip> #include <cctype> #include <array> #include <unordered_map>
typedef long long ll; typedef std::pair<ll,ll> pll; typedef std::array<ll,3> arr; const ll MAXN=static_cast<ll>(1e5)+10; std::set<ll> ali;
std::unordered_map<ll,ll> li; ll N,T,A[MAXN],tr[MAXN],K;
inline ll lowbit(ll x){ return x&(-x); }
inline void add(ll x){ ll idx=li[x]; while (idx<=N) { tr[idx]+=1; idx+=lowbit(idx); } }
inline ll query(ll x){ ll idx=li[x]; ll res=0; while(idx>0){ res+=tr[idx]; idx-=lowbit(idx); } return res; }
inline void init(){ ali.clear(); li.clear(); for(int i=0;i<=N+5;++i) tr[i]=0; }
inline void solve(){ init(); for(int i=1;i<=N;++i){ std::cin>>A[i]; ali.insert(A[i]); } ll idx=0; for(std::set<ll>::iterator it=ali.begin();it!=ali.end();it++){ li[*it]=++idx; } ll cnt=0,op=0; for(int i=1;i<=N;++i){ ll lcnt=std::max((i-1-query(A[i])),0LL); cnt+=lcnt; add(A[i]); } cnt=std::max(cnt-K,0LL); std::cout<<cnt<<"\n"; }
int main() { std::ios::sync_with_stdio(false); std::cin.tie(0);std::cout.tie(0); while (std::cin>>N>>K) { solve(); } return 0; }
|
心路历程(WA,TLE,MLE……)