题目
曾大仙非常擅长数学,同时也非常擅长做沙雕,所谓沙雕就是用沙子做成的雕像,某天他决定要在广外建一个沙雕广场,他需要把一个大小为wh的沙雕放在大小为nm的广场中,不过在放沙雕之前,需要现在广场上建一个雕像的底座,底座要求严格包含雕像,即假设底座大小为x*y,则 w+2<=x<=n,h+2<=y<=m。(雕像,广场和底座均由单位1组成,详见提示)
问:
现在有多少种满足条件的放雕像的方案?由于方案数过多,请将答案对1e9 + 7取余
注:
1.方案不同,当且仅当底座大小或者底座位置或雕像位置不同。
2.雕像不可旋转放置,即w对应n,h对应m:
3.雕像必须与底座平行,即 w与n平行,h与m平行,即不能斜着放
思路
一开始没注意数据,直接写了个O(n2)的解法,给TLE了。
所以列出式子,提取公因数,可以写出一个O(n)的解法。
具体步骤如下图:
一开始看到别人都是1ms过的,觉得是能够推出一条O(1)的公式的。
不过我这个O(n)的算法时间是0ms,emmmm…………,那其他人应该也是这样做的了。
代码
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
int main()
{
int n, m, w, h;
scanf("%d %d %d %d", &n, &m, &w, &h);
ll x = n - w - 2, y = m - h - 2;
ll num = 0;
for(int i = 1; i <= y + 1; i++)
num = (num + i * (y + 1 - i + 1) % mod) % mod;
ll ans = 0;
for(int i = 1; i <= x + 1; i++)
{
ans = (ans + i * (x + 1 - i + 1) % mod * num % mod) % mod;
}
printf("%lld\n", ans);
return 0;
}