題解 CF1292A 【NEKO's Maze Game】


有一個結論:

\((1,1)\) 不能抵達 \((2,n)\) 時,必定存在一個點對,這兩個點的值均為真,且坐標中的 \(x\) 互異,\(y\) 的差 \(\leq 1\)

這個結論的正確性感覺非常顯然,就不多說了。

下圖可以形象地解釋點對的位置關系。

那對於每個點的值,只要開一個數組 f[i][j] 記錄一下即可。


有了上述結論,我們記一個變量 \(cnt\) 表示 " 有多少對滿足上述結論的點對 " ,則 \(cnt=0\) 時,\((1,1)\) 可以抵達 \((2,n)\) ,反之不可抵達。重點在於如何維護 \(cnt\)

對於每次反轉的點 \((x,y)\) ,我們都需要往 \(cnt\) 里 扣除 \(/\) 補上 \((x,y)\) 的貢獻,具體的:(為了方便異或 \(x\)\(0\)\(1\)

\(f[x][y]=1\) ,令 \(cnt-=f[x \ xor \ 1][y-1]+f[x \ xor \ 1][y]+f[x \ xor \ 1][y+1]\)\(f[x][y]=0\)

\(f[x][y]=0\) ,令 \(cnt+=f[x \ xor \ 1][y-1]+f[x \ xor \ 1][y]+f[x \ xor \ 1][y+1]\)\(f[x][y]=1\)

這樣就可以起到維護 \(cnt\) 的效果了,時間復雜度 \(O(n)\)


Code 部分

#include<cstdio>

#define RI rgeister int

using namespace std;

inline int read()
{
	int x=0,f=1;char s=getchar();
	while(s<'0'||s>'9'){if(s=='-')f=-f;s=getchar();}
	while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
	return x*f;
}

const int N=100100;

int n,q;

int f[2][N];

int cnt;

int main()
{
	n=read(),q=read();

	while(q--)
	{
		int x=read()-1,y=read();
		switch(f[x][y])
		{
			case 1:{
				cnt-=f[x^1][y-1]+f[x^1][y]+f[x^1][y+1];
				f[x][y]=0;
				break;
			}

			case 0:{
				cnt+=f[x^1][y-1]+f[x^1][y]+f[x^1][y+1];
				f[x][y]=1;
				break;
			}
		}

		puts(!cnt?"Yes":"No");
	}

	return 0; 
}

\[thanks \ for \ watching \]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM