| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 1352 | Accepted: 509 |
Description
Input
Output
Sample Input
1 3 1 2 3
Sample Output
1
<span style="font-size:18px;"><strong>首先按照等级值排序 ,那么接下来把研究问题集中到 对下标的研究,根据题目要求可以枚举排序后的每一个点找一找位置比它小的 ,和比他大的,
然后两边结果相乘(乘法原理)。结果就是以此点作为裁判时,可以举行的比赛场数。sum(i)-1 为左边小于新插入的数的个数,i-sum(i)-1
为左边大于新插入的元素个数,per【i】.id- 1-(sum(i)-1)为此点右边元素下标小于此点的个数。n-( i-sum(i)-1)-per【i】.id为
右边元素下标大于此点下标的个数。 过程中保证了等级值一定位于每个元素枚举时的两边。</strong></span>
<pre name="code" class="cpp">#include<iostream>
#include<sstream>
#include<algorithm>
#include<cstdio>
#include<string.h>
#include<cctype>
#include<string>
#include<cmath>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
using namespace std;
const int INF=200003;
int cnt[INF];
struct A
{
int v,id;
} per[INF];
bool cmp1(A a,A b)
{
return a.v<b.v;
}
bool cmp2 ( A a, A b)
{
return a.v>b.v;
}
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int val)
{
while(x<INF)
{
cnt[x]+=val;
x+=lowbit(x);
}
}
int sum(int x)
{
int s=0;
while(x>0)
{
s+=cnt[x];
x-=lowbit(x);
}
return s;
}
int main()
{
int t,n;
cin>>t;
while(t--)
{
cin>>n;
memset(cnt,0,sizeof(cnt));
long long ans=0;
for(int i=1; i<=n; i++)
{
scanf("%d",&per[i].v);
per[i].id=i;
}
sort(per+1,per+n+1,cmp1);
for(int i=1; i<=n; i++)
{
add(per[i].id,1);
long long Lmin=sum(per[i].id)-1;
long long Lmax=i-Lmin-1;
ans+=( n-Lmax-per[i].id)*Lmin+Lmax*(per[i].id-Lmin-1);
}
cout<<ans<<endl;
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/lsgqjh/article/details/47017435