Reverse It HDU - 6513 (去重)
题目链接:
Reverse It
题目大意:给你一个n*m的01矩阵,然后你最多对这个矩阵的子矩阵进行翻转两次(0变成1,1变成0)。问你最多有多少个不同的矩阵?
学习网址:
HDU - 6513 Reverse It (SYSU校赛C题)(组合数学+容斥)
感谢lxw的讲解,
具体思路:
AC代码:
1 #include<bits/stdc++.h>
2 using namespace std;
3 # define ll long long
4 # define inf 0x3f3f3f3f
5 const int maxn = 2e5+100;
6 ll com(ll n,ll m) {ll ret=1; for(ll i=1; i<=m; ++i)ret=ret*(n-i+1)/i; return ret;}
7 int main()
8 {
9 ll n,m;
10 while(~scanf("%lld %lld",&n,&m))
11 {
12 char u;
13 for(int i=1; i<=n; i++)
14 {
15 for(int j=1; j<=m; j++)
16 scanf(" %c",&u);
17 }
18 ll tot=com(n+1ll,2ll)*com(m+1ll,2ll)*(com(n+1ll,2ll)*(com(m+1ll,2ll))-1ll)/2ll;
19 tot-=(n-1ll+m-1ll-1ll)*com(n+1ll,2ll)*com(m+1,2ll);
20
21 tot-=2ll*2ll*com(n+1ll,3ll)*com(m+1ll,3ll);
22
23 tot-=2ll*(com(n+1ll,2ll)*com(m+1ll,4ll)+com(n+1ll,4ll)*com(m+1ll,2ll));
24
25 tot-=2ll*4ll*(com(n+1ll,3ll)*com(m+1ll,3ll));
26 tot+=1ll;
27
28 printf("%lld\n",tot);
29 }
30 return 0;
31 }