codeforces 1598 D.Training Session(组合计数+思维)
题目链接
题意:
\(n\)个问题,每个问题有两个属性\(a\)、\(b\),求任意选取三个问题满足属性\(a\)互不相同,或者\(b\)互不相同的方案数。
思路:
不满足的必符合以下情况之一:
(1)选取的三个问题中属性\(a\)有两个相同或全相同。
(2)选取的三个问题中属性\(b\)有两个相同或全相同。
故不满足的情况共有三种。
题目说明没有两个问题有相同的\(a\)、\(b\)属性。所以当三个问题\(a\)属性全相同时,\(b\)属性必互不相同,\(b\)属性全相同时同理。
所以不满足的情况只有选取的三个问题中恰有两个问题\(a\)相同,\(b\)相同。
code:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <deque>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
// #include <unordered_map>
#define fi first
#define se second
#define pb push_back
// #define endl "\n"
#define debug(x) cout << #x << ":" << x << endl;
#define bug cout << "********" << endl;
#define all(x) x.begin(), x.end()
#define lowbit(x) x & -x
#define fin(x) freopen(x, "r", stdin)
#define fout(x) freopen(x, "w", stdout)
#define ull unsigned long long
#define ll long long
const double eps = 1e-15;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double pi = acos(-1.0);
const int mod = 998244353;
const int maxn = 1e6 + 10;
using namespace std;
int ca[maxn], cb[maxn], a, b, n;
vector<int> v[maxn];
void solve(){
scanf("%d", &n);
for(int i = 1; i <= n; i ++)ca[i] = cb[i] = 0, v[i].clear();
for(int i = 1; i <= n; i ++){
scanf("%d%d", &a, &b);
ca[a] ++, cb[b] ++;
v[a].pb(b);
}
ll ans = 1ll * n * (n - 1) * (n - 2) / 6;
for(int i = 1; i <= n; i ++){
for(int j = 0; j < v[i].size(); j ++){
ans -= 1ll * (ca[i] - 1) * (cb[v[i][j]] - 1);
}
}
cout << ans << endl;
}
int main(){
int t;
scanf("%d", &t);
while(t --)solve();
return 0;
}

浙公网安备 33010602011771号