见过几次坐标旋转的,还是没掌握到精髓啊,完全没往这边想。
这题的转变很巧妙。旋转了45度,每步就变成(x+1,y+1),(x+1,y-1),(x-1,y+1),(x-1,y-1)四种选择。
这样每一步x和y都会变化,就可以独立分开考虑了。
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
using namespace std;
class WolfPack {
public:
int calc(vector<int> , vector<int> , int);
};
long long pmod = 1000000007;
vector<long long> x, y;
long long ba[100005], rba[100005];
long long pwmd(long long a, long long k) {
long long ret = 1;
while (k) {
if (k & 1)
ret = a * ret % pmod;
a = a * a % pmod;
k >>= 1;
}
return ret;
}
void pre() {
int i;
ba[0] = rba[0] = 1;
ba[1] = rba[1] = 1;
for (i = 2; i < 100005; ++i) {
ba[i] = ba[i - 1] * i % pmod;
rba[i] = rba[i - 1] * pwmd(i, pmod - 2) % pmod;
}
}
long long C(int n, int k) {
return ba[n] * rba[k] % pmod * rba[n - k] % pmod;
}
int WolfPack::calc(vector<int> xx, vector<int> yy, int m) {
int i, k;
int n = xx.size();
pre();
x.clear();
y.clear();
for (i = 0; i < n; ++i) {
x.push_back(xx[i] + yy[i]);
y.push_back(xx[i] - yy[i]);
}
long long ans1, ans2, p;
sort(x.begin(), x.end());
ans1 = 0;
for (k = x[x.size() - 1] - m; k <= x[0] + m; k += 2) {
p = 1;
for (i = 0; i < x.size(); ++i) {
long long r;
r = m - abs(x[i] - k);
if (r % 2)
p *= 0;
else {
p *= C(m, r / 2);
p %= pmod;
}
}
ans1 += p;
ans1 %= pmod;
}
sort(y.begin(), y.end());
ans2 = 0;
for (k = y[y.size() - 1] - m; k <= y[0] + m; k += 2) {
p = 1;
for (i = 0; i < y.size(); ++i) {
long long r;
r = m - abs(y[i] - k);
if (r % 2)
p *= 0;
else {
p *= C(m, r / 2);
p %= pmod;
}
}
ans2 += p;
ans2 %= pmod;
}
return ans1 * ans2 % pmod;
}