【Blue Bridge Cup】【AcWing】1236. Incremental Triple

topic description

Increment triplet

Given three integer arrays
A=[A1,A2,…AN],
B=[B1,B2,…BN],
C=[C1,C2,…CN],
please count how many triples (i,j,k) satisfy:
1 ​​≤ i, j, k ≤ N
Ai < Bj < Ck

Input Format
The first line contains an integer N.
The second line contains N integers A1, A2,...AN.
The third line contains N integers B1,B2,...BN.
The fourth line contains N integers C1, C2, ... CN.

Output Format
An integer representing the answer.

Data range
1≤N≤10 5 ,
0≤Ai,Bi,Ci≤10 5

Input sample:

3
1 1 1
2 2 2 
3 3 3

Sample output:

27

problem solving ideas

For each Bi, how many are smaller than Bi in A, and how many are larger than Bi in C, multiplied to the number of triplets.
cnt[i] indicates how many times the value i appears in A/C.
s[i] is the prefix and array of cnt, indicating how many times 0-i appears in A/C.
s[3] = 3 means that the numbers from 0 to 3 in A/C appear 3 times.
How many numbers in A are smaller than Bj --> s[Bj - 1]
How many numbers in C are greater than Bj --> c - s[Bj]

Method 1:
Method 2:

Code

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
int n;
int a[N], b[N], c[N];
int as[N]; // as[i] 表示在A中有多少个数小于b[i]
int cs[N]; // cs[i] 表示在C中有多少个数大于b[i]
int cnt[N], s[N];
int main()
{
    
    
    cin >> n;
    // 把每个数都加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] ++;
    // 求as[]
    for (int i = 0; i < n; i ++) cnt[a[i]] ++;
    for (int i = 1; i < N; i ++) s[i] = s[i - 1] + cnt[i];
    for (int i = 0; i < n; i ++) as[i] = s[b[i] - 1];
    // 求cs[]
    memset(s, 0, sizeof s);
    memset(cnt, 0, sizeof cnt);
    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];
    // 3 * 3 + 3 * 3 + 3 * 3 = 27
    cout << res << endl;
}

Guess you like

Origin blog.csdn.net/laaa123mmm/article/details/128743434