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

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. 1i,j,kN1≤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。

输出格式

一个整数表示答案。

数据范围

1N1051≤N≤105,
0Ai,Bi,Ci105

代码:
复制代码
#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;
}
复制代码

 

posted @   zzq12138  阅读(73)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示