码迷,mamicode.com
首页 > 其他好文 > 详细

LA 4329 Ping pong

时间:2016-04-07 20:52:02      阅读:133      评论:0      收藏:0      [点我收藏+]

标签:

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int Max=20010;
const int inf=100000;
int lm[Max],rm[Max],a[Max],c[Max*10];
int n;
long long lowbit(long long x)
{
    return x&-x;
}
int sum(long long x,int *c)
{
    int ret=0;
    while(x>0)
    {
        ret+=c[x];
        x-=lowbit(x);
    }
    return ret;
}
void add(long long x,int d,int *c)
{
    while(x<=inf)      //从x到inf的数组都拥有一个小于等于x的数:x
    {
        c[x]+=d;
        x+=lowbit(x);
    }
}
int main()
{
    int T;
    for(scanf("%d",&T);T;T--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        memset(c,0,sizeof(c));
        add(a[1],1,c);
        for(int i=2;i<=n;i++)
        {
            lm[i]=sum(a[i],c);
            add(a[i],1,c);
        }
        memset(c,0,sizeof(c));
        add(a[n],1,c);
        for(int i=n-1;i>=1;i--)
        {
            rm[i]=sum(a[i],c);
            add(a[i],1,c);
        }
        long long ans=0;
        for(int i=1;i<=n;i++)
        {
  //          cout<<i<<" lm: "<<lm[i]<<" rm: "<<rm[i]<<endl;
            ans+=lm[i]*(n-i-rm[i])+(i-1-lm[i])*rm[i];
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

题意:n个人,每个人都有一个能力值,每次举办比赛都要三个人,举办条件:

如果 i,j,k进行比赛时,如果k是裁判,必须要i<j<k(下标)而且ai<aj<ak(能力值)

思路:只要枚举每个人当裁判是他左边小于他的数个数lm和他右边小于他的数的个数rm

那么答案就是(左边总人数-lm)*(rm)+(lm)*(右边总人数-rm)

如果对每个lm和rm进行枚举的话那么时间会是n^2

可以对树状数组的add操作加以改变,将从ci数组定以为此时ai出现之前的小于ai的数的个数

动态加一,然后求1到ai的sum值

 

LA 4329 Ping pong

标签:

原文地址:http://www.cnblogs.com/zsyacm666666/p/5365015.html

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