Educational Codeforces Round 115 (Rated for Div. 2) D

本文解析了一个关于给定n个二元组的组合问题,目标是找出满足xi和yi唯一性的三个二元组的解决方案。通过逆向思维和排列组合,作者提供了计数不合法方案后求解有效方案的方法,涉及到了高中数学知识,如使用map记录元素频率并计算组合数。
摘要由CSDN通过智能技术生成

题意大概是这样的
给出n个二元组(xi,yi) 要求我们选定三个二元组 满足以下条件:

1.三组的xi互不相同

2.三组的yi互不相同

答案是求有多少种方案满足以上的一个或者多个条件。
用到的思想和高中排列组合的知识比较像,因为正着考虑每一种合法的情况比较复杂,种类也比较多,所以我们可以倒过来考虑,求出每一个不合法的方案,再用总方案数减去不合法的方案数就可以了

具体思路:
想要不合法的话,上面的两个条件,有一个不满足的就可以了
现在我们随机取一对数字,假设xi为a,yi为b,现在我们已经有b这一种了,第二个,我们可以在剩下的yi为b的数对里,随意挑换一个数队,也就是cnt[b]-1,现在我们的第二个数字已经挑好了,第三个数字也是同理,只不过考虑的是a,在剩下的yi为b的数对里,随意挑选一个数对,也就是cnt[a]-1;
答案的公式就是这样了,我们只需要在一开始的时候,开3个容器记录特们出现的次数就可以了

代码


#include <bits/stdc++.h>
#define int long long
#define gcd __gcd
#define endl '\n'
#define mem(x, y) memset(x, y, sizeof(x))
#define inf 0x3f3f3f
#define ninf 0xc0c0c0c0
#define FAST ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
using namespace std;
typedef pair<int, int> PII;
const int N = 200010;
void solve()
{
    map<int, int> m1, m2;
    map<int, vector<int>> m3;
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        int x, y;
        cin >> x >> y;
        m1[x]++, m2[y]++;
        m3[y].push_back(x);
    }
    int ans = 0;
    for (int i = 0; i < m3.size(); i++)
    {
        int tmp = 0;
        for (auto it : m3[i])
        {
            tmp += m1[it] - 1;
        }
        ans += tmp * (m2[i] - 1);
    }
    cout << n * (n - 1) * (n - 2) / 6 - ans << endl;
}
signed main()
{
    FAST;
    int t;
    cin >> t;
    while (t--)
        solve();
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值