poj 3928

来源:互联网 发布:大阪七将星数据 编辑:程序博客网 时间:2024/05/07 03:51

题目链接:http://poj.org/problem?id=3928

思路:分别用树状数组统计b[i](a[1],a[2]...a[i-1]中比a[i]小的个数)和d[i](a[i+1],a[i+2]...a[n]中比a[i]小的个数) a[i]~a[i-1]a[i]a[i+1]~a[n]比a[i]小的个数b[i] d[i]比a[i]大的个数i-1-b[i] n-i-d[i]则如果i为裁判则有b[i]*(n-i-d[i])+d[i]*(i-1-b[i])种情况。

注意:ans为__int64;

#include<cstdio>#include<cstring>using namespace std;const int num=100005;const int N=20005;int c[num],b[N],d[N],data[N],n;int lowbit(int a){    return a&(-a);}void updata(int a,int add){    while(a<=num)    {        c[a]+=add;        a+=lowbit(a);    }}int sum(int a){    int ans=0;    while(a>0)    {        ans+=c[a];        a-=lowbit(a);    }    return ans;}int main(){    int t,i;    __int64 ans;    //freopen("in.txt","r",stdin);    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        ans=0;        memset(c,0,sizeof(c));        for(i=1;i<=n;i++)        {            scanf("%d",&data[i]);            b[i]=sum(data[i]-1);            updata(data[i],1);        }        //for(i=1;i<=5;i++) printf("%d ",b[i]);printf("\n");        for(i=1;i<=n;i++)            d[i]=sum(data[i]-1)-b[i];        //for(i=1;i<=5;i++) printf("%d ",d[i]);printf("\n");        for(i=1;i<=n;i++)        {            ans+=((i-1-b[i])*d[i]+b[i]*(n-i-d[i]));        }        printf("%I64d\n",ans);    }    return 0;}


0 0
原创粉丝点击