记录编号 |
582511 |
评测结果 |
AAAAAAAAAA |
题目名称 |
三元数对 |
最终得分 |
100 |
用户昵称 |
┭┮﹏┭┮ |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.014 s |
提交时间 |
2023-09-16 21:08:07 |
内存使用 |
2.75 MiB |
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 3e4+10;
int n,top;//top为离散化后数据
ll c[N],r[N];
ll ans;
struct made{
int id;
ll d,x;
}a[N];
bool cmp1(made x,made y){
return x.x < y.x;
}
bool cmp2(made x,made y){
return x.id < y.id;
}//先离散化再返回
void add(int x,ll z){
while(x <= n+1){
c[x] += z;
x += x&-x;
}
return;
}
int ask(int x){
ll ss = 0;
while(x > 0){
ss += c[x];
x -= x&-x;
}
return ss;
}
int main(){
freopen("three.in","r",stdin);
freopen("three.out","w",stdout);
scanf("%d",&n);
for(int i = 1;i <= n;i++){
scanf("%lld",&a[i].x);
a[i].id = i;
}
sort(a+1,a+1+n,cmp1);
for(int i = 1;i <= n;i++){
if(a[i].x != a[i-1].x)top++;
a[i].d = top;
}//离散化
sort(a+1,a+1+n,cmp2);
for(int i = n;i >= 1;i--){
r[i] = ask(n-a[i].d);
add(n-a[i].d+1,1);
}
memset(c,0,sizeof(c));
for(int i = 1;i <= n;i++){
ans += r[i] * ask(a[i].d-1);
add(a[i].d,1);
}//树状数组求两边逆序对
printf("%lld\n",ans);
return 0;
}