码迷,mamicode.com
首页 > 编程语言 > 详细

UVALive 4329--Ping pong+树状数组

时间:2015-06-20 09:21:27      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:uva   树状数组   

题目链接:点击进入
开始的时候想着枚举两个比赛的选手,然后再求在他们中间有多少个满足要求的裁判,但是这样时间复杂度就不可能满足题目的要求.后面觉得可以枚举每个人做裁判的情况;假设第i位选手做裁判,然后设其左边1–i-1中有lmin[i]个人的排名比他低,则有i-1-lmin[i]个人的排名不比他低,设其右边i+1–n中有rmin[i]个人的排名比他低,则有n-i-rmin[i]个人的排名不比他低.则第i位选手做裁判时,可以举行的比赛数为lmin[i](n-i-rmin[i])+rmin[i](i-1-lmin[i])。所以现在的问题在于求出每位选手左右的rmin和lmin。
在这里我们可以假定有一个排名数组c[],其中c[i]=x表示有x个人处于第i名的位置。然后现在我们要求第i位选手左边有多少个人的排名比它的低;我们可以将它左边的所有选手的排名都插入这个数组中,然后查询c[1]+c[2]+…+c[a[i]-1]的值就行了。所以我们只要对所有选手从左到右进行查询和更新就行了,这里可以用线段树或是树状数组实现。对于每个选手右边的情况也可以类似处理。

代码如下:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;

#define maxn 100010
#define ll long long

int a[maxn],C[maxn*4],m;
int lmin[maxn],rmin[maxn];

int lowbit(int x)
{
    return x&(-x);
}

int sum(int x)
{
    int ret=0;
    while(x>0)
    {
        ret+=C[x];
        x-=lowbit(x);
    }
    return ret;
}

void add(int x,int d)
{
    while(x<=m)
    {
        C[x]+=d;
        x+=lowbit(x);
    }
}

int main()
{
      //freopen("in.txt","r",stdin);
       int t;
       scanf("%d",&t);
       while(t--)
       {
             int n;
             m=0;
             scanf("%d",&n);
             for(int i=1;i<=n;i++)
             {
                 scanf("%d",&a[i]);
                 m=max(m,a[i]);
             }
             memset(C,0,sizeof(C));
             memset(lmin,0,sizeof(lmin));
             memset(rmin,0,sizeof(rmin));
             for(int i=1;i<=n;i++)
             {
                    lmin[i]=sum(a[i]-1);
                    add(a[i],1);
              }
              memset(C,0,sizeof(C));
              for(int j=n;j>=1;j--)
              {
                    rmin[j]=sum(a[j]-1);
                    add(a[j],1);
               }
               ll ans=0;
               for(int i=2;i<n;i++)
               {
                     ans+=(ll)lmin[i]*(n-i-rmin[i]);
                     ans+=(ll)rmin[i]*(i-1-lmin[i]);
               }
               printf("%lld\n",ans);
       }
   return 0;
}

UVALive 4329--Ping pong+树状数组

标签:uva   树状数组   

原文地址:http://blog.csdn.net/acm_lkl/article/details/46564149

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!