标签:
藏妹子之处(excel)
6 19 4 18776
输出示例
116280
不难发现,不共线的三点的曼哈顿距离和等于一个矩形的周长,而共线的三点俩俩曼哈顿距离和等于最远两个点曼哈顿距离×2.
注意到题目说两点不能再同一行同一列,所以我们可以平面上这三个点分别投影到x轴和y轴上。投影后x轴、y轴上各有三点。
相反地,在x轴、y轴上分别找3点,也可以将它还原成平面上3个点的状态,所以可以分别算出确定x轴、y轴上三点的方案数Ax和Ay
不难得出当最远两点距离为i,总共有n个位置时Axi = (n - i) * (i - 1).
Ayi的计算方法同理。
x轴、y轴上的点找好后,剩下的问题就是还原成平面上3个点的状态了,设x轴上三个点为X1, X2, X3,y轴上三点Y1, Y2, Y3。
那么当X1, X2, X3顺序确定后,Y1, Y2, Y3的每一个排列都能还原成一个状态,所以方案数为6Axi · Ayj
代码如下:
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <stack> #include <vector> #include <queue> #include <cstring> #include <string> #include <map> #include <set> using namespace std; int read() { int x = 0, f = 1; char c = getchar(); while(!isdigit(c)){ if(c == ‘-‘) f = -1; c = getchar(); } while(isdigit(c)){ x = x * 10 + c - ‘0‘; c = getchar(); } return x * f; } #define maxn 4010 #define MOD 1000000007 #define LL long long int n, m, mint, maxt; LL an[maxn], am[maxn], ans; void solve() { for(int i = 1; i <= n; i++) for(int j = 1; j <= m && ((i + j) << 1) <= maxt; j++) if(mint <= ((i + j) << 1)) (ans += ((an[i] * (am[j] * 6 % MOD)) % MOD)) %= MOD; return ; } int main() { n = read(); m = read(); mint = read(); maxt = read(); for(int i = 1; i <= n; i++) an[i] = (LL)(n - i) * (i - 1) % MOD; for(int i = 1; i <= m; i++) am[i] = (LL)(m - i) * (i - 1) % MOD; solve(); printf("%lld\n", ans); return 0; }
标签:
原文地址:http://www.cnblogs.com/xiao-ju-ruo-xjr/p/4888285.html