【数位DP】luogu_P7415 Count the Cows G

题意

对于每一个满足\(x≥0\)以及\(y≥0\)的方格\((x,y)\),当对于所有整数\(k≥0\)\(\left\lfloor \frac{x}{3^k}\right\rfloor\)\(\left\lfloor \frac{y}{3^k}\right\rfloor\)除以三的余数的奇偶性均相同时,有一头奶牛位于\((x,y)\)
换言之,两个余数均为奇数(均等于\(1\)),或均为偶数(均等于\(0\)\(2\))。

例如,满足\(0≤x,y<9\)的方格中,包含奶牛的方格在下图中用 1 表示。

        x
    012345678

  0 101000101
  1 010000010
  2 101000101
  3 000101000
y 4 000010000
  5 000101000
  6 101000101
  7 010000010
  8 101000101

他进行了 QQ 个询问,每个询问由三个整数\(x_i,y_i,d_i\)组成。
对每个询问,FJ想要知道有多少奶牛位于\((x_i,y_i)\)\((x_i+d_i,y_i+d_i)\)的对角线上的方格内(包括两端)。

思路

先对一个\(k\)进行分析。
\(x=3^ka+r_0\)
\(y=3^kb+r_1\)
​因为研究\(a\)\(b\)的关系,再提一个\(3\)
\(x=3^k(3p_x+q_x)+r_0\)
\(y=3^k(3p_y+q_y)+r_1\)
展开即为:
\(x=3^{k+1}p_x+3^kq_x+r_0\)
\(y=3^{k+1}p_y+3^kq_y+r_1\)
对于\(r_0\),\(r_1\),我们也可以将它们分成包含若干\(3\)的次幂的式子。
最后变成三进制的形式。
\(x = \sum_{k = 0} 3^k a_{k}\)
\(y = \sum_{k = 0} 3^k b_{k}\)
在上面分析过,单独对于每个k来看,\(a_k\)\(b_{k}\)\(\% 2\)同余。

故满足条件的\((x,y)\)\(x、y\)在三进制情况下的每位\(\% 2\)同余。

用数位dp计算即可。

代码

#include <cstdio>
#include <cstring>

const int n = 38;
int q;
int X[39], Y[39], D[39], v[39][2][2][2];
long long f[39][2][2][2];

int check(int a, int b) {
	if (a < 0 || a > 2 || b < 0 || b > 2)
		return 0;
	return (a & 1) == (b & 1);
}

long long dp(int dep, int a, int b, int flag) {//当前数位,是否向dep+1进位,,d有没有顶到
	if (dep < 0)
		return !a && !b;
	if (v[dep][a][b][flag])
		return f[dep][a][b][flag];
	v[dep][a][b][flag] = 1;
	long long res = 0;
	for (int i = 0; i <= (flag ? D[dep] : 2); i++)//flag的体现
		for (int j = 0; j <= 1; j++)//枚举下一位要不要向当前位进位
			for (int k = 0; k <= 1; k++)
				if (check(X[dep] - 3 * a + i + j, Y[dep] - 3 * b + i + k))
					res += dp(dep - 1, j, k, flag & (D[dep] == i));
	return f[dep][a][b][flag] = res;
}

int main() {
	scanf("%d", &q);
	long long d, x, y;
	while (q--) {
		memset(v, 0, sizeof(v));
		scanf("%lld %lld %lld", &d, &x, &y);
		for (int i = 0; i <= n; i++) {
			X[i] = x % 3;
			x /= 3;
			Y[i] = y % 3;
			y /= 3;
			D[i] = d % 3;
			d /= 3;
		}
		printf("%lld\n", dp(n, 0, 0, 1));
	}
}
posted @ 2021-08-16 21:36  nymph181  阅读(66)  评论(0)    收藏  举报