Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 2641 | Accepted: 978 |
Description
Input
Output
Sample Input
1 3 1 2 3
Sample Output
1
题目大意:给定几个ping pong玩家,每个玩家都有唯一的技能值。每个玩家按东西方向排成一列。问从中选两个玩家,再选一个裁判。裁判在位置上在两个玩家之间(当然不能是其中一个玩家)。裁判的技能 值必须在两个玩家之间(注意:每个玩家的技能值都是唯一的)。三个人组成一个组合,只要其中有一个人不同就算不同的组合,问共有多少种组合?
思路:如果从玩家的角度解题,那么会TLE。从裁判的角度看,就是从找出位置在其左方且技能值比其小的玩家个数 x 位置在其右方且技能值比其大的玩家个数 + 位置在其左方且技能值比其大的玩家个数 x 位置在其右方且技能值比其小的玩家个数
#include"cstdio" #include"cstring" #include"algorithm" using namespace std; const int MAXN=20005; const int N=100005; typedef long long LL; struct Node{ int id,x; }a[MAXN]; bool comp(const Node &a,const Node &b) { return a.x < b.x; } int bit[N]; int n; int lowbit(int i) { return i&(-i); } void add(int i,int x) { while(i<=MAXN) { bit[i]+=x; i+=lowbit(i); } } LL sum(int i) { LL s=0; while(i>0) { s+=bit[i]; i-=lowbit(i); } return s; } int main() { int T; scanf("%d",&T); while(T--) { memset(bit,0,sizeof(bit)); scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d",&a[i].x); a[i].id=i+1; } sort(a,a+n,comp); int lmin; int rmin; LL res=0; for(int i=0;i<n;i++) { lmin=sum(a[i].id-1);//zuoxiao rmin=sum(n)-sum(a[i].id); res+=(lmin*(n-a[i].id-rmin)); res+=(rmin*(a[i].id-lmin-1)); add(a[i].id,1); } printf("%lld\n",res); } return 0; } /* 1 5 1 3 5 2 4 res:3 */
原文:http://www.cnblogs.com/program-ccc/p/5138306.html