口胡一下各种时间复杂度(也许吧)的方法
So1ution1So1ution1So1ution1:直接上暴力
时间复杂度O(n2logn)\text{时间复杂度}O(n^{2}logn)时间复杂度O(n2logn)
Solution2Solution2Solution2: 考虑到相邻 kkk 之间变化量等于所有 k+1k+1k+1 变到 kkk 导致逆序对的减量之和,因此算这个然后逆着推。
Solution3Solution3Solution3(正解):优化一下的方法应该很容易想到吧,可以转化为一个类似求逆序对的一个东东,然后就显然了。
注意开long long
CodeCodeCode
#include<cstdio>
#define ll long long
const int N = 1e5 + 5;
ll n, a[N], s[N], ans, t[N];
ll lowbit(ll x){return x & (-x);}
void update(ll x){while(x <= n) t[x]++, x += lowbit(x);}
ll query(ll x){ll ret = 0; while(x) ret += t[x], x -= lowbit(x); return ret;}
int main()
{
freopen("haircut.in","r",stdin);
freopen("haircut.out","w",stdout);
scanf("%lld", &n);
for(int i = 1; i <= n; i++) scanf("%lld", &a[i]), a[i]++;
for(int i = 1; i <= n; i++)
s[a[i]] += query(n - a[i] + 1), update(n - a[i] + 2);
for(int i = 0; i < n; i++) ans += s[i], printf("%lld\n", ans);
return 0;
}
本文探讨了三种不同的算法解决方案,分别采用暴力破解、相邻元素变化量计算和逆序对求解的方法,针对特定问题进行时间复杂度的优化,从O(n^2logn)到更高效的实现。
366






