CF 15B【Laser】、C 【Industrial Nim】

B

题意

给出\(n\times m\)的一块巧克力,再给出两个点,两点只能同时移动,两点所占位置巧克力会融化,问所有能走位置走遍之后还剩下几块巧克力。

Idea

题目就是给两个矩形,然后算两个点所走位置的并集对于全集的补集。点都可以变成左上方一个点和右下方,然后可以分成两种情况。第一种是两个所走矩形不相交,第二种是相交。
如图
0.001.jpg
求蓝色部分的面积

Code

//n,m<=le9->m*n<=1e18,要开long long
signed main(){ 
	int T=read();
	while(T--){
		int n=read(),m=read(),x1=read(),yy=read(),x2=read(),y2=read();
		int a,b,sum;
		if(yy>y2) swap(yy,y2);
		if(x1>x2) swap(x1,x2);
		a=abs(x2-x1); b=abs(y2-yy);
		a=x1+n-x2; b=yy+m-y2;
		sum=a*b*2;
		if(a*2>n&&b*2>m) sum-=(a*2-n)*(b*2-m);
		sum=n*m-sum;
		printf("%I64d\n",sum);
	} 
	return 0;
}

C

Idea

本题的暴力的话,就是裸的\(NIM\)游戏,将每堆石子的数量异或一下,判断如果异或和不为零的话,先手必胜,否则后手必胜。但我们发现这个算法的瓶颈在于\(m\)的值非常大,我们试想一下是否可以快速求一段区间的异或和。
对于区间\([l,r]\)的异或值,等价于\([1,l-1] Xor [1,r]\),因为异或两遍\([1,l-1]\)区间相当于没异或。我们的目标就是求出\([1,x]\)
先打表
0.02.png
\(i \bmod 4=1\;sum=1\)
\(i \bmod 4=2\;sum=i+1\)
\(i \bmod 4=3\;sum=0\)
\(i \bmod 4=0\;sum=i\)

Code


inline int solve(int x){
	if(x==0) return 0;
	if(x%4==1) return 1;
	if(x%4==2) return x+1;
	if(x%4==3) return 0;
	if(x%4==0) return x;
}
signed main(){ 
	int n=read(); int flag=0;
	for(int i=1;i<=n;i++){
		int x=read(),m=read();
		int l=x,r=x+m-1;
		flag^=solve(r)^solve(l-1);
	}
	if(flag) puts("tolik");
	else puts("bolik");
	return 0;
}
posted @ 2019-09-09 18:49  云山乱  阅读(276)  评论(0编辑  收藏  举报