【USACO 2021FEB G】Count the Cows

【USACO 2021FEB G】Count the Cows

by AmanoKumiko

Description

如同平常一样,Farmer John 的奶牛们分散在他的最大的草地上。草地可以看作是一个由正方形方格组成的巨大的二维方阵(想象一个巨大的棋盘)。

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

FJ 对他的草地上的某个特定区域内的奶牛数量感兴趣。他进行了 \(Q\) 个询问,每个询问由三个整数 \(x_i,y_i,d_i\) 组成。对每个询问,FJ 想要知道有多少奶牛位于 \((x_i,y_i)\)\((x_i+d_i,y_i+d_i)\) 的对角线上的方格内(包括两端)。

Input

询问数\(Q\)

以下\(Q\)行,每行三个数\(d,x,y\)

Output

输出\(Q\)行,每个询问输出一行。

Sample Input

8
10 0 0
10 0 1
9 0 2
8 0 2
0 1 7
1 1 7
2 1 7
1000000000000000000 1000000000000000000 1000000000000000000

Sample Output

11
0
4
3
1
2
2
1000000000000000001

Data Constraint

1<=Q<=10000,1<=xi,yi<=1000000000000000000

Solution

研究条件,倒序枚举\(k\)

(三进制下)在最高位时,必须保证两数奇偶性相同

到下一位时,需保证前两位的和的奇偶性相同

由于最高位已经相同,那只需要保证当前位奇偶性相同

以此类推,条件转化为三进制下,\(x,y\)的每一位的奇偶性相同

可以直接数位dp

\(f[i][ix][iy][lim]\)

表示做到第\(i\)位,低位的\(x,y\)是否进位,以及\(d\)的限制是否顶满

转移显然

Code

#include<bits/stdc++.h>
using namespace std;
#define F(i,a,b) for(int i=a;i<=b;i++)
#define Fd(i,a,b) for(int i=a;i>=b;i--)
#define LL long long
#define S 40

int q,numd[S],numx[S],numy[S];
LL d,x,y,f[S][2][2][2];

void ch(LL v,int *A){F(i,0,38)A[i]=v%3,v/=3;}

bool check(int x,int y){return (x<0||y<0||x>2||y>2?0:x%2==y%2);}

LL dfs(int x,int ix,int iy,int lim){
	if(x<0)return (ix==iy&&ix==0);
	if(f[x][ix][iy][lim]!=-1)return f[x][ix][iy][lim];
	LL res=0;int up=lim?2:numd[x];
	F(i,0,up) F(le,0,1) F(ri,0,1)if(check(numx[x]+le-3*ix+i,numy[x]+ri-3*iy+i)){
		res+=dfs(x-1,le,ri,lim|(i<numd[x]));
	}
	return (f[x][ix][iy][lim]=res);
}

int main(){
	scanf("%d",&q);
	while(q--){
		scanf("%lld%lld%lld",&d,&x,&y);
		memset(f,-1,sizeof(f));
		ch(d,numd);ch(x,numx);ch(y,numy);
		printf("%lld\n",dfs(38,0,0,0));
	}
	return 0;
}
posted @ 2021-08-19 11:30  冰雾  阅读(123)  评论(0编辑  收藏  举报