【树】【dfs】【模拟】I Like Matrix Forever!

DescriptionDescription

对一个 n ∗ m 的零矩阵 A 进行 q 次操作:
• 1 i j:将 Ai,j 取反;
• 2 i:将矩阵 A 第 i 行的所有元素全部取反;
• 3 j:将矩阵 A 第 j 列的所有元素全部取反;
• 4 k:将矩阵 A 还原为第 k 次操作之后的状态。
进行每一次操作之后,询问当前矩阵所有元素的和。

InputInput

第一行包含三个整数 n,m 和 q。
之后 q 行每行包含两个或三个整数,表示一次操作的所有参数。

OutputOutput

共 q 行每行包含一个整数 ans,表示当前矩阵所有元素的和。

SampleSample InputInput

2 2 4
2 1
1 1 2
4 1
3 2

SampleSample OutputOutput

2
1
2
2

ExplainExplain

TrainTrain ofof ThoughtThought

可以看成一个树,如图:
【树】【dfs】【模拟】I Like Matrix Forever!
新的操作与上一个操作连接起来,然后模拟三种操作,dfs就可以了
必须要用快读和快输(否则会TLE)

CodeCode

#include<cstdio>
#include<iostream>
using namespace std;
int N,M,m[1005][1005],t,q,h[100005],ans[100005],sum,l[100005],x[100005],y[100005];
int read() 
{
	int x=0,flag=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')flag=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*flag;
}//快读
void write(int x)
{
    if(x<0) {x=-x;putchar('-');}
	if(x>9) write(x/10);
	putchar(x%10+48);
	return;
}//快输
struct node
{
	int to,from;
}w[100001];
void link(int x,int y)
 {w[++t]=(node){y,h[x]}; h[x]=t;}
void dfs(int dep)
{
	if (l[dep]==1) {
		sum+=1-(m[x[dep]][y[dep]]<<1);
		m[x[dep]][y[dep]]=!m[x[dep]][y[dep]];
	}
	if (l[dep]==2) {
		for (int i=1; i<=M; ++i)
		{
			sum+=1-(m[x[dep]][i]<<1);
			m[x[dep]][i]=!m[x[dep]][i];
		}
	}
	if (l[dep]==3) {
		for (int i=1; i<=N; ++i)
		{
			sum+=1-(m[i][x[dep]]<<1);
			m[i][x[dep]]=!m[i][x[dep]];
		}
	}//模拟
	ans[dep]+=sum;
	for (int i=h[dep];i;i=w[i].from) dfs(w[i].to);//继续往下搜
	if (l[dep]==1) {
		sum+=1-(m[x[dep]][y[dep]]<<1);
		m[x[dep]][y[dep]]=!m[x[dep]][y[dep]];
	}
	if (l[dep]==2) {
		for (int i=1; i<=M; ++i)
		{
			sum+=1-(m[x[dep]][i]<<1);
			m[x[dep]][i]=!m[x[dep]][i];
		}
	}
	if (l[dep]==3) {
		for (int i=1; i<=N; ++i)
		{
			sum+=1-(m[i][x[dep]]<<1);
			m[i][x[dep]]=!m[i][x[dep]];
		}
	}//还原回去
}
int main()
{
	N=read(); M=read(); q=read();
	for (int i=1; i<=q; ++i)
	{
		l[i]=read(); x[i]=read();
		if (l[i]==1) y[i]=read();
		if (l[i]!=4) link(i-1,i);//连接上一点的操作
		 else link(x[i],i);//连接回到哪个点
	}
	dfs(0);
	for (int i=1; i<=q; ++i)
	 write(ans[i]),putchar(10);
}