前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >AcWing 2455 合法三元组的个数 Solution

AcWing 2455 合法三元组的个数 Solution

作者头像
Skykguj
发布2022-09-09 12:07:58
5630
发布2022-09-09 12:07:58
举报
文章被收录于专栏:Skykguj 's BlogSkykguj 's Blog

题目链接

2455. 合法三元组的个数

给定三个数组 A, B, C,以及一个非负整数 d。求共有多少个三元组 (i, j, k),满足 ... 输出一个整数,用来表示满足条件的三元组的个数。

题目大意

给定三个数组 A, B, C,以及一个非负整数 d。求共有多少个三元组 (i, j, k),满足:|A_i - B_j| \le d, |A_i - C_k| \le d, |B_j - C_k| \le d

解题思路

双指针常用于解决计数类问题。

如果把 A,B,C 三个数组合并到一个数组 D 中,并将 D 数组排序,问题就转化为求所有满足 D[j] - D[i] 的区间中能选出多少个 A, B, C;考虑到直接枚举区间的时间复杂度较高,而 D 数组具有单调性,因此可以使用双指针中的快慢指针来选择区间。

算法流程

还没写~

Code

代码语言:javascript
复制
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <utility>

const int MAXN = 300010;
typedef std::pair<int, int> PII;
typedef long long ll;
#define val first
#define id second

int n, d, cnt[3][MAXN];
PII D[MAXN];

void prework()
{
    std::sort(D + 1, D + n + 1);
    for (int i = 0; i < 3; i ++ )
        for (int j = 1; j <= n; j ++ )
            cnt[i][j] = cnt[i][j - 1] + (D[j].id == i);
}

void solve()
{
    int last = -1; // 上一次快指针的位置。
    ll res = 0;
    for (int i = 1, j = 1; i <= n; i ++ )
    {
        while (j <= n && D[j].val - D[i].val <= d) j ++ ;
        if (j > last)
        {
            int cnta = cnt[0][j - 1] - cnt[0][i - 1];
            int cntb = cnt[1][j - 1] - cnt[1][i - 1];
            int cntc = cnt[2][j - 1] - cnt[2][i - 1];
            res += (ll)cnta * cntb * cntc;
        }
        if (i <= last && last < j)
        {
            int cnta = cnt[0][last - 1] - cnt[0][i - 1];
            int cntb = cnt[1][last - 1] - cnt[1][i - 1];
            int cntc = cnt[2][last - 1] - cnt[2][i - 1];
            res -= (ll)cnta * cntb * cntc;
        }
        last = j;
    }
    printf("%lld\n", res);
}

int main()
{
    int l1, l2, l3, x;
    scanf("%d%d%d%d", &l1, &l2, &l3, &d);
    for (int i = 0; i < l1; i ++ )
    {
        scanf("%d", &x);
        D[++ n] = std::make_pair(x, 0);
    }
    for (int i = 0; i < l2; i ++ )
    {
        scanf("%d", &x);
        D[++ n] = std::make_pair(x, 1);
    }
    for (int i = 0; i < l3; i ++ )
    {
        scanf("%d", &x);
        D[++ n] = std::make_pair(x, 2);
    }

    prework();
    solve();
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022 年 04 月,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目链接
  • 题目大意
  • 解题思路
  • 算法流程
  • Code
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档