递增三元组(蓝桥杯模拟题)

2022/2/19 23:16:46

本文主要是介绍递增三元组(蓝桥杯模拟题),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1236. 递增三元组

 

给定三个整数数组

A=[A1,A2,…AN]A=[A1,A2,…AN],
B=[B1,B2,…BN]B=[B1,B2,…BN],
C=[C1,C2,…CN]C=[C1,C2,…CN],

请你统计有多少个三元组 (i,j,k)(i,j,k) 满足:

  1. 1≤i,j,k≤N1≤i,j,k≤N
  2. Ai<Bj<CkAi<Bj<Ck

输入格式

第一行包含一个整数 NN。

第二行包含 NN 个整数 A1,A2,…ANA1,A2,…AN。

第三行包含 NN 个整数 B1,B2,…BNB1,B2,…BN。

第四行包含 NN 个整数 C1,C2,…CNC1,C2,…CN。

输出格式

一个整数表示答案。

数据范围

1≤N≤1051≤N≤105,
0≤Ai,Bi,Ci≤105

代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long LL;//数据范围大,计算过程会爆int
const int N=100010;
int a[N],b[N],c[N];
int as[N],cs[N];//as[i]表示在a[]中有多少个数小于b[i],cs[i]表示在c[]中有多少有多少个数大于b[i]
int cnt[N],s[N];//cnt[i]表示i在a或c数组中出现的次数,s数组是cnt的前缀和数组,s[i]表示cnt中前i个数的和
int main(){
    int n;
    scanf("%d",&n);
    //因为数据范围从0开始,所以要让3个数组的所有数都加1,
    //避免可能出现出现数组下标为负数的空指针异常( for(int i=0;i<n;i++) as[i]=s[b[i]-1])
    for(int i=0;i<n;i++) scanf("%d",&a[i]),a[i]++;
    for(int i=0;i<n;i++) scanf("%d",&b[i]),b[i]++;
    for(int i=0;i<n;i++) scanf("%d",&c[i]),c[i]++;
    for(int i=0;i<n;i++) cnt[a[i]] ++;
    for(int i=1;i<N;i++) s[i]=s[i-1]+cnt[i];//求cnt[]的前缀和,i(3个数组中的数)的大小不能超过数据范围N
    for(int i=0;i<n;i++) as[i]=s[b[i]-1];
    memset(cnt,0,sizeof cnt);
    memset(s,0,sizeof s);//清空两个数组
    for(int i=0;i<n;i++) cnt[c[i]]++;
    for(int i=1;i<N;i++) s[i]=s[i-1]+cnt[i];
    for(int i=0;i<n;i++) cs[i]=s[N-1]-s[b[i]];
    LL res=0;
    for(int i=0;i<n;i++) res+=(LL)as[i]*cs[i];
    cout<<res<<endl;
    return 0;
}

 



这篇关于递增三元组(蓝桥杯模拟题)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程