poj 1804Brainman(树状数组)

来源:互联网 发布:五阿哥和知画圆房视频 编辑:程序博客网 时间:2024/06/04 18:16

题目连接:http://poj.org/problem?id=1804

题目解析:

                       此题和

poj2299 Ultra-QuickSort(http://poj.org/problem?id=2299)一样,

属于树状数组的离散化的题目,就是求一组数据的逆序数。由于给的的数据不连

续而且还有负数就想到用树状数组的离散化。

(离散化http://blog.csdn.net/infinitezhen/article/details/9327453)

    错误分析:在排序的时候一开始是

bool cmp(node o1,node o2){    return o1.val<o2.val;}

就是直接排序了。

改过之后:

bool cmp(node o1,node o2){    if(o1.val==o2.val)        return o1.order<o2.order;    else    return o1.val<o2.val;}
理由:要考虑到数据有相同的,故也要对坐标排序。


#include<stdio.h>#include <iostream>#include<string.h>#include<stdlib.h>#include<math.h>#include<algorithm>#include<list>#include<vector>#pragma comment(linker,"/STACK:102400000,102400000")using namespace std;#define MAX 2000005int tree[MAX],aa[MAX];int n;struct node{    int val;    int order;}p[MAX];bool cmp(node o1,node o2){    if(o1.val==o2.val)        return o1.order<o2.order;    else    return o1.val<o2.val;}int lowbit(int idx){    return idx&(-idx);}void update(int idx,int val){    while(idx<=MAX)    {        tree[idx]+=val;        idx+=lowbit(idx);    }}int sum(int idx){    int sum=0;    while(idx>0)    {        sum+=tree[idx];        idx-=lowbit(idx);    }    return sum;}int main(){    int val,i,t,count=1;   // freopen("in.txt","r",stdin);    scanf("%d",&t);    while(t--)    {        memset(tree,0,sizeof(tree));        scanf("%d",&n);        for(i=1;i<=n;i++)        {            scanf("%d",&p[i].val);            p[i].order=i;        }        sort(p+1,p+n+1,cmp);        for(i=1;i<=n;i++)        {            aa[p[i].order]=i;        }        long long ans=0;        for(i=1;i<=n;i++)        {            update(aa[i],1);            ans+=i-sum(aa[i]);        }        printf("Scenario #%d:\n",count++);        printf("%lld\n",ans);            printf("\n");    }    return 0;}