【Codechef】CNTDSETS
题面
求出\(n\)维空间中的点集数目,满足其直径恰好为\(D\)。点集的直径是点集中最远一对
点的切比雪夫距离。如果两个点集可以通过平移相互转换,则这两个点集是相同的。
题解
直接蒯Anson爷的题解了:
平移的限制可以理解为每一维都存在该维坐标为\(0\)的点(认为所有坐标都是非负整数)。这样一来,距离限制也可以转化为至少有一维的最大坐标为\(D\)。
考虑计算最大值小于等于\(x\)的方案\(f(x)\),容斥“每一维都存在0“。
答案就是
\[Ans=f(D)-f(D-1)\\
f(D)=\sum_{i=0}^n(-1)^i{n\choose i}2^{d^i(d+1)^{n-i}}
\]
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
inline int gi() {
register int data = 0, w = 1;
register char ch = 0;
while (!isdigit(ch) && ch != '-') ch = getchar();
if (ch == '-') w = -1, ch = getchar();
while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar();
return w * data;
}
const int Mod = 1e9 + 7, Phi = Mod - 1;
int fpow(int x, int y, int m) {
int res = 1;
while (y) {
if (y & 1) res = 1ll * res * x % m;
x = 1ll * x * x % m;
y >>= 1;
}
return res;
}
const int MAX_N = 2e3 + 5, MAX = 2e3;
int N, D, C[MAX_N][MAX_N];
int f(int d) {
int res = 0, p = 1;
for (int i = 0; i <= N; i++) {
res = (res + 1ll * p * C[N][i] % Mod *
fpow(2, 1ll * fpow(d, i, Phi) * fpow(d + 1, N - i, Phi) % Phi, Mod)) % Mod;
p = Mod - p;
}
return res;
}
int main () {
for (int i = 0; i <= MAX; i++) C[i][0] = C[i][i] = 1;
for (int i = 1; i <= MAX; i++)
for (int j = 1; j < i; j++) C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % Mod;
int T = gi();
while (T--) {
N = gi(), D = gi();
printf("%d\n", (f(D) - f(D - 1) + Mod) % Mod);
}
return 0;
}