#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int Max=;
const int inf=;
int lm[Max],rm[Max],a[Max],c[Max*];
int n;
long long lowbit(long long x)
{
return x&-x;
}
int sum(long long x,int *c)
{
int ret=;
while(x>)
{
ret+=c[x];
x-=lowbit(x);
}
return ret;
}
void add(long long x,int d,int *c)
{
while(x<=inf)
{
c[x]+=d;
x+=lowbit(x);
}
}
int main()
{
int T;
for(scanf("%d",&T);T;T--)
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
}
memset(c,,sizeof(c));
add(a[],,c);
for(int i=;i<=n;i++)
{
lm[i]=sum(a[i],c);
add(a[i],,c);
}
memset(c,,sizeof(c));
add(a[n],,c);
for(int i=n-;i>=;i--)
{
rm[i]=sum(a[i],c);
add(a[i],,c);
}
long long ans=;
for(int i=;i<=n;i++)
{
// cout<<i<<" lm: "<<lm[i]<<" rm: "<<rm[i]<<endl;
ans+=lm[i]*(n-i-rm[i])+(i--lm[i])*rm[i];
}
printf("%lld\n",ans);
}
return ;
}

题意: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值

最新文章

  1. vue2.0环境搭建
  2. 迷你MVVM框架 avalonjs 入门教程
  3. C#入门经典Lambda
  4. 小米网站登录源码C#版
  5. cygwin 安装apt-cyg命令
  6. Windows 8 开发系列汇总
  7. Python脚本模拟登录网页之CSDN篇
  8. [MODx] 3. Working with chunks, TV, Category
  9. 利用Excel批量高速发送电子邮件
  10. WINDOWS硬件通知应用程序的常方法
  11. 全球(局)唯一标识符GUID的使用
  12. java根据概率生成数字
  13. Hibernate执行SQL语句实现查询修改功能!
  14. Palindromic characteristics CodeForces - 835D (区间DP,预处理回文串问题)
  15. thinkphp验证码不显示
  16. Codeforces 1139D Steps to One dp
  17. NET的基本用法
  18. opencv学习笔记(三)
  19. EM算法——Expectation-Maximization
  20. Exp7:网络欺诈防范

热门文章

  1. HDFS01
  2. J - 玩游戏
  3. balsamiq mockups 注册
  4. mkisofs
  5. ckeditor详细设置
  6. Vue Router的params和query传参的使用和区别
  7. 微信小程序后台获取用户的opeid
  8. [转]linux之awk命令
  9. ansj --词性说明
  10. PHP第二阶段学习 一、php的基本语法