hdu 5497 Inversion(树状数组)
生活随笔
收集整理的這篇文章主要介紹了
hdu 5497 Inversion(树状数组)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=5497
解題思路:
用樹狀數(shù)組維護(hù)一段區(qū)間L,區(qū)間長度為m,依次枚舉該區(qū)間的終點ai,即將該點加入到區(qū)間L來,把ai-m從原來的L中刪除;
刪去ai+m,影響就是少了后面所有比它小的逆序對數(shù),以及前面所有比它大的逆序對數(shù)?
添加ai,同理,多了所有比它小的逆序對數(shù),以及前面所有比它大的逆序對數(shù)?
這里用到了兩個樹狀數(shù)組,比較難理解。
#include<iostream> #include<cstdio> #include<cstring> using namespace std;const int maxn = 100005; struct Tree {int n,c[maxn];void init(int n){this->n = n;memset(c,0,sizeof(c));}int lowbit(int x){return x & -x;}void add(int i,int d){while(i <= n){c[i] += d;i += lowbit(i);}}int sum(int x){int ans = 0;while(x){ans += c[x];x -= lowbit(x);}return ans;} }L,R; int n,m,a[maxn];int main() {int t;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);for(int i = 1; i <= n; i++)scanf("%d",&a[i]);L.init(n);R.init(n);long long tmp = 0,ans;for(int i = m + 1; i <= n; i++){tmp += i - m - 1 - R.sum(a[i]);R.add(a[i],1);}ans = tmp;for(int i = m + 1; i <= n; i++){tmp -= R.sum(a[i]-1);tmp -= L.sum(n) - L.sum(a[i]);R.add(a[i],-1);tmp += R.sum(a[i-m]-1);tmp += L.sum(n) - L.sum(a[i-m]);L.add(a[i-m],1);ans = min(ans,tmp);}printf("%lld\n",ans);}return 0; }總結(jié)
以上是生活随笔為你收集整理的hdu 5497 Inversion(树状数组)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JEECG 3.6.3版本发布 企业
- 下一篇: Windows环境配置Apache+My