其他分享
首页 > 其他分享> > 递增三元组(蓝桥杯模拟题)

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

作者:互联网

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;
}

 

标签:cnt,数组,NN,int,模拟题,蓝桥,B2,C2,三元组
来源: https://www.cnblogs.com/z218/p/15913465.html