【树状数组】 HDOJ 1394 Minimum Inversion Number

来源:互联网 发布:点对点网络测速工具 编辑:程序博客网 时间:2024/05/01 21:55

树状数组求逆序数问题,每次把最前面的数放到最后面,问最小的逆序数是多少。。注意到题目中数是1-n就比较容易想到解法了,不过如果不是1-n也可以先离散再做。。。先用树状数组求一次初始顺序的,再依次把当前的逆序减去这个数再减1(也就是这个数后面比他小的数的个数),然后加上n减这个数(就是这个数前面比他大的数的个数)。。。最后加上一个输入加速,程序直接跑到第一面了~~~


#include <iostream>#include <sstream>#include <algorithm>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <bitset>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <climits>#define maxn 5001#define eps 1e-6#define mod 1000000007#define INF 99999999#define lowbit(x) (x&(-x))#define lson o<<1, L, mid#define rson o<<1 | 1, mid+1, Rtypedef long long LL;using namespace std;int tree[maxn];int num[maxn];int n, tmp;void add(int x){for(int i=x;i<=n;i+=lowbit(i)) tree[i]+=1;}int sum(int x){int ans=0;for(int i=x;i>0;i-=lowbit(i)) ans+=tree[i];return ans;}void work(void){int i, ans=0;memset(tree, 0, sizeof tree);for(i=n;i>0;i--){ans+=sum(num[i]);add(num[i]);}tmp=ans;}int get(void){int temp=0;char ch=getchar();while(ch>='0' && ch<='9')temp=temp*10+ch-'0', ch=getchar();return temp+1;}int main(void){int i, mi;while(scanf("%d",&n)!=EOF){getchar();for(i=1;i<=n;i++) num[i]=get();work();mi=tmp;for(i=1;i<n;i++){tmp-=num[i]-1;tmp+=n-num[i];if(tmp<mi) mi=tmp;}printf("%d\n",mi);}return 0;}


0 0
原创粉丝点击