题解 CF1598D Training Session

\[\text{题目大意} \]

\(\quad\)\(n\) 组数,每组数包含一个 \(a_i,b_i\)(\(a_i,b_i \leq n\)),从 \(n\) 组数中选择 \(3\) 组数,满足 \(a\) 全不同或 \(b\) 全不同,问有多少种方案数?

\[\text{思路} \]

\(\quad\)考虑容斥原理,首先总共的方案数为

\[C_n^3=\frac{n\times (n-1)\times (n-2)}{6} \]

\(\quad\)题目中还有一个条件是没有两组数的 \(a\)\(b\) 完全相同,所以最多 \(a\) 不同或 \(b\) 不同。考虑不符合题目要求的情况,即满足既有 \(a\) 相同,又有 \(b\) 相同的三组数的方案数。

\(\quad\)对于第 \(i\) 组数,与 \(a_i\) 相同的数的个数为 \(num1\) ,与 \(b_i\) 相同的数的个数为 \(num2\),设 \(j,k\) 满足 \(a_j=a_i,b_k=b_i\),由题可得 \(b_j\neq b_k,a_j\neq a_k\),即不会重复计数,显然除了 \(i\) 本身以外所有的 \(j\)\(k\) 可以自由组合,所以可得:

\[ans=C_n^3-\displaystyle\sum_{i=1}^{n}(num1[a_i]-1)\times(num2[b_i]-1) \]

\(\quad\)多组数据,记得清空数组,并且要开 long long。

const int N=2e5+5;
int T,n,num1[N],num2[N],a[N],b[N],ans;
il int num(int x){return x*(x-1)*(x-2)/6;}
signed main()
{
	T=read();
	while(T--){
		n=read();ans=0;
		for(re i=1;i<=n;i++)
		{
			a[i]=read();b[i]=read();
			num1[a[i]]++;num2[b[i]]++;
		}
		for(re i=1;i<=n;i++)ans+=(num1[a[i]]-1)*(num2[b[i]]-1);
		for(re i=1;i<=n;i++)num1[a[i]]=0,num2[b[i]]=0;
		print(num(n)-ans);putchar('\n');
	}
	return 0;
}
posted @ 2021-10-25 21:11  Farkas_W  阅读(37)  评论(0编辑  收藏  举报