標簽:eof 答案 versions ret ack namespace val 數組 memset
題意:
每次翻轉一段區間,詢問翻轉區間后整個序列的逆序對數量。
題解:
每次翻轉區間,那么翻轉區間的答案就是整個序列的原始答案減去這個區間里逆序對的數量加上順序對的數量。
統計逆序對和順序對用樹狀數組做。
#include<bits/stdc++.h> using namespace std; const int maxn=1010; int n; int a[maxn]; int c[maxn]; int lowbit(int x) { return x&-x; } void add (int x,int val) { for (int i=x;i<=n;i+=lowbit(i)) c[i]+=val; } int getsum (int x) { int ans=0; for (int i=x;i;i-=lowbit(i)) ans+=c[i]; return ans; } vector<int> ans; int main () { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",a+i); int wjm=0; for (int i=1;i<=n;i++) { wjm+=getsum(n)-getsum(a[i]); add(a[i],1); } for (int i=1;i<=n;i++) { memset(c,0,sizeof(c)); int sum=0; int sum_=0;//順序對數量 for (int j=i;j<=n;j++) { sum+=getsum(n)-getsum(a[j]); sum_+=getsum(a[j]); //翻轉一段區間,答案就是總的逆序對數量減去這個區間內的逆序對數量加上這個區間的順序對數量 ans.push_back(wjm-sum+sum_); add(a[j],1); } // } for (int i=0;i<ans.size();i++) { if (i) printf(" "); printf("%d",ans[i]); } }
PAT-T1027 Larry and Inversions (樹狀數組)
標簽:eof 答案 versions ret ack namespace val 數組 memset
原文地址:https://www.cnblogs.com/zhanglichen/p/13357042.html