poj 3928 Ping pong

来源:互联网 发布:软件自学网cad2016 编辑:程序博客网 时间:2024/05/19 17:48

Description

N(3<=N<=20000) ping pong players live along a west-east street(consider the street as a line segment). Each player has a unique skill rank. To improve their skill rank, they often compete with each other. If two players want to compete, they must choose a referee among other ping pong players and hold the game in the referee's house. For some reason, the contestants can't choose a referee whose skill rank is higher or lower than both of theirs. The contestants have to walk to the referee's house, and because they are lazy, they want to make their total walking distance no more than the distance between their houses. Of course all players live in different houses and the position of their houses are all different. If the referee or any of the two contestants is different, we call two games different. Now is the problem: how many different games can be held in this ping pong street?

Input

The first line of the input contains an integer T(1<=T<=20), indicating the number of test cases, followed by T lines each of which describes a test case. 
Every test case consists of N + 1 integers. The first integer is N, the number of players. Then N distinct integers a1, a2 ... aN follow, indicating the skill rank of each player, in the order of west to east. (1 <= ai <= 100000, i = 1 ... N).

Output

For each test case, output a single line contains an integer, the total number of different games. 

Sample Input

1 3 1 2 3

Sample Output

1
题意:n个人,每个人有一个ID和一个技能值,一场比赛需要两个选手和一个裁判,只有当裁判的ID和技能值都在两个选手之间的时候才能进行一场比赛,现在问一共能组织多少场比赛。

这道题目是简单的树状数组统计问题。首先我们要对技能值从小到大排序,然后利用每一个选手的ID对树状数组进行维护.

每次维护一个ID之前先查询sum(ID) 与sum(n)-sum(ID)

当前维护ID :i 那么sum(ID)可知是所有ID小于i且能力值小于I的人(之前排序后,在i维护之前所有人的能力值都小于等于i),同理sum(n)-sum(ID)是ID大于i但能力值小于i的人,将两个值分别记为 l和r

那么当i当裁判时可以举办l*(n-i-r)+r*(i-1-l), 求出所有人当裁判的可能,就是我们要统计的答案。

#include<iostream>#include<cstring>#include<algorithm>using namespace std;#define maxn 22000typedef long long ll;int c[maxn],n;ll ans;struct node{    int id,r;}p[maxn];bool cmp(node a,node b){    return a.r<b.r;}int lowbit(int x){    return x&(-x);}int sum(int x){    int s=0;    while(x>0)    {        s+=c[x];        x-=lowbit(x);    }    return s;}void add(int i,int x){    while(i<=n)    {        c[i]+=x;        i+=lowbit(i);    }}int main(){    int i,t;    cin>>t;    while(t--)    {        cin>>n;        for(i=1;i<=n;i++)        {            cin>>p[i].r;            p[i].id=i;        }        sort(p+1,p+1+n,cmp);        memset(c,0,sizeof c);        ans=0;        ll l,r;        for(i=1;i<=n;i++)        {            l=sum(p[i].id);            r=sum(n)-l;            ans+=l*(n-p[i].id-r)+r*(p[i].id-1-l);            add(p[i].id,1);        }        cout<<ans<<endl;    }    return 0;}




0 0
原创粉丝点击