gdl全场1血的题(2019东秦寒假训练营) Apare_xzc
据gdl说是他在东秦寒假全国训练营某场比赛全场1血的题
xzc 2019/03
题意:
给一个m乘n的矩阵,矩阵里面只有0和1,
定义f(i)为所有子矩阵里面数字之等于i的个数
令tot = m*n
求i从0到tot f(i)*i的和
思路:
这道题我想了想,还挺有意思的,和我昨天刚补的16年Asia Final H题(闷声发大财H题)思路差不多,比那道题简单很多
这道题就是统计1对计数的贡献,只要求出某个位置被几个矩阵包含即可
它自己肯定要选的,方案数就是横向拓展的方案乘以纵向拓展的方案
横向左边可以拓展0,1,2,…一直到左边框,右边同理
所以(i,j)的贡献就是 i*(m-i+1)*j*(n-j+1)
代码实现:
#include <bits/stdc++.h>
#define LL long long
#define For(i,a,b) for(long long i=(a);i<=(b);++i)
using namespace std;
const int mod = 1e9+7;
int a[2000+1][2000+1];
LL m,n;
void solve();//蛮力法(肯定会TLE)
int main()
{
std::ios::sync_with_stdio(false);
LL res(0);
while(cin>>m>>n)
{
res = 0;
For(i,1,m)
For(j,1,n)
cin>>a[i][j];
For(i,1,m)
For(j,1,n)
{
if(!a[i][j]) continue;
res += (i*(m-i+1)*j%mod*(n-j+1)%mod);
if(res>=mod) res%=mod;
}
cout<<res<<endl;
//solve();
}
return 0;
}
void solve() //蛮力法
{
int res = 0;
For(U,1,m)
For(D,U,m)
For(L,1,n)
For(R,L,n)
{
int ans = 0;
For(i,U,D)
For(j,L,R)
{
ans += a[i][j];
}
res += ans;
}
cout<<res<<endl;
}