POJ3928

来源:互联网 发布:java cmd运行 编辑:程序博客网 时间:2024/06/05 19:56
对于原数据a[],树状数组c[],c[n]表示的段是c[n]=a[n-2^k+1]+....a[n],其中k是n在二进制下末尾0的个数,比如n=6(110)对于的k就是1;//树状数组来做;#include <iostream>#include<string.h>#include<stdio.h>#include<algorithm>using namespace std;const int maxn=100005;const int maxm=20005;int  c[maxn];int  rank1[maxm];int  d[maxn];int left1[maxm];int right1[maxm];int n;int lowbit(int x){    return (x&-x);}void update(int x,int c1){    int i;    //cout<<"hah"<<" ";    for(i=x;i<=n;i+=lowbit(i))    {        c[i]+=c1;    }}int getsum(int x){    int i;    int ans=0;    for(i=x;i>0;i-=lowbit(i))    {        ans+=c[i];    }    return ans;}int main(){    int case1;    scanf("%d",&case1);    while(case1--)    {        memset(c,0,sizeof(c));        int i;        scanf("%d",&n);        for(i=0;i<n;i++)        {            scanf("%d",&rank1[i]);            d[rank1[i]]=i;        }        sort(rank1,rank1+n);//这一步也很关键        for(i=0;i<n;i++)        {            rank1[i]=d[rank1[i]]+1;        }        memset(left1,0,sizeof(left1));        memset(right1,0,sizeof(right1));        for(i=0;i<n;i++)        {           // cout<<"haha"<<endl;            left1[i]=getsum(rank1[i]);//这一步是关键            update(rank1[i],1);        }        //cout<<121<<endl;        memset(c,0,sizeof(c));        for(i=n-1;i>=0;i--)        {            right1[i]=getsum(rank1[i]);            update(rank1[i],1);        }        long long ans=0;        for(i=0;i<n;i++)        {            ans+=left1[i]*(n-i-1-right1[i])+(i-left1[i])*right1[i];        }        printf("%lld\n",ans);    }    return 0;}

0 0
原创粉丝点击