设 $f(p)$ 为逆序对数量,$d(p)$ 为 D 题答案,$e(p)$ 为 E 题答案。
列出等式 $2d(p)-e(p)=f(p)$。
移项得 $e(p)=2d(p)-f(p)$。
使用树状数组计算 $f(p)$,使用上一题的代码计算 $d(p)$,输出 $2d(p)-f(p)$ 即可。
感性理解一下,我们的 D 题是一个最小化策略,而逆序对也是一个最小化的策略,如果将任意一个变大,第二个的变小量都不超过这个的变大量,所以拼出的也是一个最小化的策略。
具体细节留给各位巨佬去证明吧,本蒟蒻太菜了,不会,如果大家想出了证明,欢迎评论。
:::
:::info[代码(Hard)]
```cpp
#include <bits/stdc++.h>
using namespace std;
#define int long long
int a[500010],sum,sum2;
int c[500010];
void insert(int id){
while (id<=500000) c[id]++,id+=(id&(-id));
}
int query(int id){
int ans=0;
while (id) ans+=c[id],id-=(id&(-id));
return ans;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n; cin>>n;
for (int i=1; i<=n; i++){
int x; cin>>x; sum+=abs(x-i); sum2+=i-1-query(x); insert(x);
}
cout<<sum-sum2<<"\n";
}
```
:::
:::error[常见错误]
不要忘记开 long long。
:::